From 4b059dcba54e463e3ffa79b910a8b79e3a5f7756 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Thu, 1 Dec 2022 13:26:40 +0200 Subject: [PATCH 1/8] Create pipeline bucket Added bucket pipelines for CI pipelines and renamed "pipelines" in ProjectOne to workflows --- _docs/pipelines/advanced-workflows.md | 972 +++++++++++++ _docs/pipelines/annotations.md | 303 ++++ _docs/pipelines/build-status.md | 151 ++ .../pipelines/condition-expression-syntax.md | 107 ++ .../conditional-execution-of-steps.md | 155 +++ _docs/pipelines/debugging-pipelines.md | 257 ++++ _docs/pipelines/docker-image-metadata.md | 219 +++ .../first-pipeline.md | 0 _docs/pipelines/hooks.md | 634 +++++++++ .../introduction-to-codefresh-pipelines.md | 341 +++++ _docs/pipelines/monitoring-pipelines.md | 464 +++++++ _docs/pipelines/pipeline-caching.md | 315 +++++ _docs/pipelines/pipelines.md | 308 +++++ _docs/pipelines/post-step-operations.md | 117 ++ _docs/pipelines/running-pipelines-locally.md | 126 ++ _docs/pipelines/secrets-store.md | 96 ++ _docs/pipelines/service-containers.md | 571 ++++++++ _docs/pipelines/shared-configuration.md | 265 ++++ _docs/pipelines/stages.md | 193 +++ _docs/pipelines/steps.md | 1223 +++++++++++++++++ _docs/pipelines/steps/approval.md | 350 +++++ _docs/pipelines/steps/build.md | 380 +++++ _docs/pipelines/steps/composition.md | 434 ++++++ _docs/pipelines/steps/deploy.md | 184 +++ _docs/pipelines/steps/freestyle.md | 353 +++++ _docs/pipelines/steps/git-clone.md | 438 ++++++ _docs/pipelines/steps/launch-composition.md | 93 ++ _docs/pipelines/steps/push.md | 257 ++++ _docs/pipelines/triggers.md | 116 ++ _docs/pipelines/triggers/azure-triggers.md | 85 ++ _docs/pipelines/triggers/cron-triggers.md | 104 ++ .../pipelines/triggers/dockerhub-triggers.md | 149 ++ _docs/pipelines/triggers/git-triggers.md | 365 +++++ _docs/pipelines/triggers/helm-triggers.md | 62 + _docs/pipelines/triggers/jfrog-triggers.md | 98 ++ _docs/pipelines/triggers/quay-triggers.md | 99 ++ _docs/pipelines/variables.md | 340 +++++ _docs/pipelines/what-is-the-codefresh-yaml.md | 378 +++++ .../concurrency-limit.md | 0 .../configure-artifact-repository.md | 0 .../create-pipeline.md | 0 .../docker-operations.md | 0 _docs/{pipelines => workflows}/marketplace.md | 0 .../nested-workflows.md | 0 .../sharing-file-system.md | 0 .../{pipelines => workflows}/using-secrets.md | 0 _docs/{pipelines => workflows}/workflows.md | 0 47 files changed, 11102 insertions(+) create mode 100644 _docs/pipelines/advanced-workflows.md create mode 100644 _docs/pipelines/annotations.md create mode 100644 _docs/pipelines/build-status.md create mode 100644 _docs/pipelines/condition-expression-syntax.md create mode 100644 _docs/pipelines/conditional-execution-of-steps.md create mode 100644 _docs/pipelines/debugging-pipelines.md create mode 100644 _docs/pipelines/docker-image-metadata.md rename _docs/{ci-cd-guides => pipelines}/first-pipeline.md (100%) create mode 100644 _docs/pipelines/hooks.md create mode 100644 _docs/pipelines/introduction-to-codefresh-pipelines.md create mode 100644 _docs/pipelines/monitoring-pipelines.md create mode 100644 _docs/pipelines/pipeline-caching.md create mode 100644 _docs/pipelines/pipelines.md create mode 100644 _docs/pipelines/post-step-operations.md create mode 100644 _docs/pipelines/running-pipelines-locally.md create mode 100644 _docs/pipelines/secrets-store.md create mode 100644 _docs/pipelines/service-containers.md create mode 100644 _docs/pipelines/shared-configuration.md create mode 100644 _docs/pipelines/stages.md create mode 100644 _docs/pipelines/steps.md create mode 100644 _docs/pipelines/steps/approval.md create mode 100644 _docs/pipelines/steps/build.md create mode 100644 _docs/pipelines/steps/composition.md create mode 100644 _docs/pipelines/steps/deploy.md create mode 100644 _docs/pipelines/steps/freestyle.md create mode 100644 _docs/pipelines/steps/git-clone.md create mode 100644 _docs/pipelines/steps/launch-composition.md create mode 100644 _docs/pipelines/steps/push.md create mode 100644 _docs/pipelines/triggers.md create mode 100644 _docs/pipelines/triggers/azure-triggers.md create mode 100644 _docs/pipelines/triggers/cron-triggers.md create mode 100644 _docs/pipelines/triggers/dockerhub-triggers.md create mode 100644 _docs/pipelines/triggers/git-triggers.md create mode 100644 _docs/pipelines/triggers/helm-triggers.md create mode 100644 _docs/pipelines/triggers/jfrog-triggers.md create mode 100644 _docs/pipelines/triggers/quay-triggers.md create mode 100644 _docs/pipelines/variables.md create mode 100644 _docs/pipelines/what-is-the-codefresh-yaml.md rename _docs/{pipelines => workflows}/concurrency-limit.md (100%) rename _docs/{pipelines => workflows}/configure-artifact-repository.md (100%) rename _docs/{pipelines => workflows}/create-pipeline.md (100%) rename _docs/{pipelines => workflows}/docker-operations.md (100%) rename _docs/{pipelines => workflows}/marketplace.md (100%) rename _docs/{pipelines => workflows}/nested-workflows.md (100%) rename _docs/{pipelines => workflows}/sharing-file-system.md (100%) rename _docs/{pipelines => workflows}/using-secrets.md (100%) rename _docs/{pipelines => workflows}/workflows.md (100%) diff --git a/_docs/pipelines/advanced-workflows.md b/_docs/pipelines/advanced-workflows.md new file mode 100644 index 00000000..06eedc38 --- /dev/null +++ b/_docs/pipelines/advanced-workflows.md @@ -0,0 +1,972 @@ +--- +title: "Advanced Workflows with Parallel steps" +description: "Learn how to create complex workflows in Codefresh with step dependencies" +group: codefresh-yaml +toc: true +--- + +Codefresh is very flexible when it comes to pipeline complexity and depth. You can easily create: + + * Sequential pipelines where step order is same as the listing order in yaml (simple) + * Sequential pipelines that have some parallel parts (intermediate) + * Parallel pipelines where step order is explicitly defined (advanced) + +With the parallel execution mode, you can define complex pipelines with fan-in/out configurations capable of matching even the most complicated workflows within an organization. + +>Notice that in Codefresh parallel execution is unrelated with [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/). Stages are only a way to visually organize your pipeline steps. The actual execution is independent from the visual layout in the logs view. + +Before going any further make sure that you are familiar with the [basics of Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). + +Codefresh offers two modes of execution: + +1. Sequential Mode (which is the default) +1. Parallel Mode + +## Sequential execution mode + +The sequential mode is very easy to understand and visualize. + +In Sequential mode the Codefresh execution engine starts from the first step defined at the top of the `codefresh.yml` file and executes all steps one by one going down to the end of the file. A step is either executed or skipped according to its conditions. The condition for each step is only examined **once**. + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +mode: sequential +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: sample-python-image + working_directory: ./ + tag: ${{CF_BRANCH_TAG_NORMALIZED}} + dockerfile: Dockerfile + MyUnitTests: + title: Running Unit tests + image: ${{MyAppDockerImage}} + commands: + - python setup.py test +{% endraw %} +{% endhighlight %} + +Here we have two steps, one that creates a Docker image and a second one that runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) inside it. The order of execution is the same order of the steps in the YAML file. This means that unit tests will always run after the Docker image creation. + +Notice that the line `mode: sequential` is shown only for illustration purposes. Sequential mode is the default, and therefore this line can be omitted. + + +## Inserting parallel steps in a sequential pipeline + +You don't have to activate parallel execution mode for the whole pipeline if only a part of it needs to run in parallel. Codefresh allows you insert a parallel phase inside a sequential pipeline with the following syntax: + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_task1: + title: My Task 1 + [...] + my_parallel_tasks: + type: parallel + steps: + my_task2a: + title: My Task 2A + [...] + my_task2b: + title: My Task 2B + [...] + my_task3: + title: My Task3 + [...] +{% endraw %} +{% endhighlight %} + + +In this case tasks 2A and 2B will run in parallel. +The step name that defines the parallel phase (`my_parallel_tasks` in the example above), is completely arbitrary. + +The final order of execution will be + +1. Task 1 +1. Task 2A and Task2B at the same time +1. Task 3 + +This is the recommended way to start using parallelism in your Codefresh pipelines and it will be enough for most scenarios that require parallelism. + +>Notice that step names should be unique within the same pipeline. The parent and child steps should NOT share the same name. + +### Example: pushing multiple Docker images in parallel + +Let's see an example where a Docker image is created and then we push it to more than one registry. This is a perfect candidate for parallelization. Here is the `codefresh.yml`: + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- build +- push +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'build' + type: build + image_name: trivialgoweb + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + PushingToRegistries: + type: parallel + stage: 'push' + steps: + jfrog_PushingTo_jfrog_BintrayRegistry: + type: push + title: jfrog_Pushing To Bintray Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + registry: bintray + PushingToGoogleRegistry: + type: push + title: Pushing To Google Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + registry: gcr + PushingToDockerRegistry: + type: push + title: Pushing To Dockerhub Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + image_name: kkapelon/trivialgoweb + registry: dockerhub +{% endraw %} +{% endhighlight %} + +The order of execution is the following: + +1. MyAppDockerImage ([build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/)) +1. jfrog_PushingTo_jfrog_BintrayRegistry, PushingToGoogleRegistry, PushingToDockerRegistry ([push steps]({{site.baseurl}}/docs/codefresh-yaml/steps/push/)) + +The pipeline view for this yaml file is the following. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/parallel-push.png" +url="/images/codefresh-yaml/parallel-push.png" +alt="Parallel Docker push" +caption="Parallel Docker push" +max-width="80%" +%} + +As you can see we have also marked the steps with [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) so that we get a visualization that matches the execution. + + +### Example: running multiple test suites in parallel + +All types of steps can by placed inside a parallel phase. Another common use case would be the parallel execution of [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) for unit/integration tests. + +Let's say that you have a Docker image with a Python back-end and a JavaScript front-end. You could run both types of tests in parallel with the following yaml syntax: + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-full-stack-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + MyTestingPhases: + type: parallel + steps: + my_back_end_tests: + title: Running Back end tests + image: ${{MyAppDockerImage}} + commands: + - python setup.py test + my_front_end_tests: + title: Running Front End tests + image: ${{MyAppDockerImage}} + commands: + - npm run test +{% endraw %} +{% endhighlight %} + +Running different types of tests (unit/integration/load/acceptance) in parallel is a very common use case for parallelism inside an otherwise sequential pipeline. + +### Defining success criteria for a parallel step + +By default, any failed step in a Codefresh pipeline will fail the whole pipeline. There are ways to change this behavior (the `fail_fast` property is explained later in this page), but specifically for parallel steps you can define exactly when the whole step succeeds or fails. + +You can define steps that will be used to decide if a parallel step succeeds with this syntax: + +{% highlight yaml %} +second_step: + title: Second step + success_criteria: + steps: + only: + - my_unit_tests + type: parallel + steps: + my_unit_tests: + title: Running Back end tests + image: node + commands: + - npm run test + my_integration_tests: + title: Running Integration tests + image: node + commands: + - npm run int-test + my_acceptance_tests: + title: Running Acceptance tests + image: node + commands: + - npm run acceptance-test +{% endhighlight %} + +In the example above, if integration and/or acceptance tests fail, the whole pipeline will continue, because we have defined that only the results of unit test matter for the whole parallel step. + +The reverse relationship (i.e., defining steps to be ignored) can be defined with the following syntax + +{% highlight yaml %} +second_step: + title: Second step + success_criteria: + steps: + ignore: + - my_integration_tests + - my_acceptance_tests + type: parallel + steps: + my_unit_tests: + title: Running Back end tests + image: node + commands: + - npm run test + my_integration_tests: + title: Running Integration tests + image: node + commands: + - npm run int-test + my_acceptance_tests: + title: Running Acceptance tests + image: node + commands: + - npm run acceptance-test +{% endhighlight %} + +In the example above we have explicitly defined that even if the integration or acceptance tests fail the whole pipeline will continue. + +### Shared Codefresh volume and race conditions + +In any pipeline step, Codefresh automatically attaches a [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that is used to transfer artifacts between steps. The same volume is also shared between steps that run in parallel. + + +Here is an example where two parallel steps are writing two files. After they finish execution, we list the contents of the project folder. + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + WritingInParallel: + type: parallel + steps: + writing_file_1: + title: Step1A + image: alpine + commands: + - echo "Step1A" > first.txt + writing_file_2: + title: Step1B + image: alpine + commands: + - echo "Step1B" > second.txt + MyListing: + title: Listing of files + image: alpine + commands: + - ls +{% endraw %} +{% endhighlight %} + +The results from the `MyListing` step is the following: + +``` +first.txt second.txt +``` + +This illustrates the side effects for both parallel steps that were executed on the same volume. + +>It is therefore your responsibility to make sure that steps that run in parallel play nice with each other. Currently, Codefresh performs no conflict detection at all. If there are race conditions between your parallel steps, (e.g. multiple steps writing at the same files), the final behavior is undefined. It is best to start with a fully sequential pipeline, and use parallelism in a gradual manner if you are unsure about the side effects of your steps + +## Implicit parallel steps +> If you use implicit parallel steps, you _cannot_ use _parallel pipeline mode_. + +In all the previous examples, all parallel steps have been defined explicitly in a pipeline. This works well for a small number of steps, but in some cases it can be cumbersome to write such a pipeline, especially when the parallel steps are similar. + +Codefresh offers two handy ways to lessen the amount of YAML you have to write and get automatic parallelization with minimum effort. + +* The `scale` syntax allows you to quickly create parallel steps that are mostly similar (but still differ) +* The `matrix` syntax allows you to quickly create parallel steps for multiple combinations of properties + +### Scale parallel steps (one dimension) + +If you look back at the parallel docker push example you will see that all push steps are the same. The only thing that changes is the registry that they push to. + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- build +- push +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'build' + type: build + image_name: trivialgoweb + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + PushingToRegistries: + type: parallel + stage: 'push' + steps: + jfrog_PushingTo_jfrog_BintrayRegistry: + type: push + title: jfrog_Pushing To Bintray Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + registry: bintray + PushingToGoogleRegistry: + type: push + title: Pushing To Google Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + registry: gcr + PushingToDockerRegistry: + type: push + title: Pushing To Dockerhub Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + image_name: kkapelon/trivialgoweb + registry: dockerhub +{% endraw %} +{% endhighlight %} + + +This pipeline can be simplified by using the special `scale` syntax to create a common parent step with all similarities: + + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- build +- push +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'build' + type: build + image_name: trivialgoweb + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + PushingToRegistries: + stage: 'push' + type: push + tag: '${{CF_SHORT_REVISION}}' + candidate: ${{MyAppDockerImage}} + scale: + jfrog_PushingTo_jfrog_BintrayRegistry: + registry: bintray + PushingToGoogleRegistry: + registry: gcr + PushingToDockerRegistry: + image_name: kkapelon/trivialgoweb + registry: dockerhub +{% endraw %} +{% endhighlight %} + +You can see now that all common properties are defined once in the parent step (`PushingToRegistries`) while each push step only contains what differs. Codefresh will automatically create parallel steps when it encounters the `scale` syntax. + +The resulting pipeline is more concise but runs in the same manner as the original YAML. For a big number of parallel steps, the `scale` syntax is very helpful for making the pipeline definition more clear. + +You can use the `scale` syntax with all kinds of steps in Codefresh and not just push steps. Another classic example would be running tests in parallel with different environment variables. + + +`YAML` +{% highlight yaml %} +{% raw %} + run_tests_in_parallel: + stage: 'Microservice A' + working_directory: './my-front-end-code' + image: node:latest + commands: + - npm run test + scale: + first: + environment: + - TEST_NODE=0 + second: + environment: + - TEST_NODE=1 + third: + environment: + - TEST_NODE=2 + fourth: + environment: + - TEST_NODE=3 +{% endraw %} +{% endhighlight %} + +This pipeline will automatically create 4 parallel freestyle steps. All of them will use the same Docker image and executed the same command (`npm run test`) but each one will receive a different value for the environment variable called `TEST_NODE`. + +Notice that if you define environment variables on the parent step (`run_tests_in_parallel` in the example above), they will also be available on the children parallel steps. And if those define, environment variables as well, all environment variables will be available. + + +### Matrix parallel steps (multiple dimensions) + +The `scale` syntax allows you to easily create multiple parallel steps that differ only in a single dimension. If you have multiple dimensions of properties that differ and you want to run all possible combinations (Cartesian product) then the `matrix` syntax will do that for you automatically. + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-unit-test' + revision: 'master' + git: github + stage: prepare + run_my_tests_before_build: + stage: test + working_directory: './golang-app-A' + commands: + - go test -v + matrix: + image: + - golang:1.11 + - golang:1.12 + - golang:1.13 + environment: + - [CGO_ENABLED=1] + - [CGO_ENABLED=0] +{% endraw %} +{% endhighlight %} + +Here we want run unit tests with 3 different versions of GO and also try with CGO enabled or not. Instead of manually writing 6 parallel steps in your pipeline with all possible combinations, we can simply use the `matrix` syntax to create the following parallel steps: + +* Go 1.11 with CGO enabled +* Go 1.11 with CGO disabled +* Go 1.12 with CGO enabled +* Go 1.12 with CGO disabled +* Go 1.13 with CGO enabled +* Go 1.13 with CGO disabled + +The resulting Codefresh YAML is much more compact. Notice that because the `environment` property in Codefresh is already an array on its own, when we use it with the `matrix` syntax we need to enclose its value with `[]` (array of arrays). + +You can add more dimensions to a matrix build (and not just two as shown in the example). Here is another example with 3 dimensions: + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/spring-boot-2-sample-app' + revision: master + git: github + MyUnitTests: + stage: test + matrix: + image: + - 'maven:3.5.2-jdk-8-alpine' + - 'maven:3.6.2-jdk-11-slim' + - 'maven:3-jdk-8' + commands: + - ["mvn --version", "mvn -Dmaven.repo.local=/codefresh/volume/m2_repository test"] + - ["mvn --version", "mvn -Dmaven.test.skip -Dmaven.repo.local=/codefresh/volume/m2_repository package"] + environment: + - [MAVEN_OPTS=-Xms1024m] + - [MAVEN_OPTS=-Xms512m] +{% endraw %} +{% endhighlight %} + +This pipeline creates 3 x 2 x 2 = 12 parallel steps with all the possible combinations of: + +* Maven version +* Running or disabling tests +* Using 1GB or 512MBs of memory. + +Remember that all parallel steps run within the same pipeline executor so make sure that you have enough resources as the number +of matrix variations can quickly grow if you add too many dimensions. + +Notice that, as with the `scale` syntax, the defined values/properties are merged between parent step (`MyUnitTests` in the example above) and children steps. For example, if you set an environment variable on the parent and also on child matrix steps , the result will a merged environment where all values are available. + +## Parallel pipeline mode +> If you use parallel pipeline mode, you _cannot_ use _implicit parallel steps_. + +To activate advanced parallel mode for the whole pipeline you need to declare it explicitly at the root of the `codefresh.yml` file: + +``` +version: '1.0' +mode: parallel +steps: +[...] +``` + +In full parallel mode, the order of steps inside the `codefresh.yml` is **not** affecting the order of execution at all. The Codefresh pipeline engine instead: + +1. Evaluates all steps conditions *at the same* time +2. Executes those that have their requirements met +3. Starts over with the remaining steps +4. Stops when there no more steps to evaluate + +This means that in parallel mode the conditions of a step are evaluated **multiple times** as the Codefresh execution engine is trying to find which steps it should run next. This implication is very important when you try to understand the order of step execution. + +Notice also that in parallel mode, if you don't define any step conditions, Codefresh will try to run **all** steps at once, which is probably not what you want in most cases. + +With parallel mode you are expected to define the order of steps in the yaml file, and the Codefresh engine will create a *graph* of execution that satisfies your instructions. This means that writing the `codefresh.yml` file requires more effort on your part, but on the other hand allows you to define the step order in ways not possible with the sequential mode. You also need to define which steps should depend on the automatic cloning of the pipeline (which is special step named `main_clone`). + +In the next sections we describe how you can define the steps dependencies in a parallel pipeline. + +### Single Step Dependencies + +At the most basic level, you can define that a step *depends on* the execution of another step. This dependency is very flexible as Codefresh allows you run a second step once: + +1. The first step is finished with success +1. The first step is finished with failure +1. The first completes (regardless of exit) status + +The syntax for this is the following post-condition: + +{% highlight yaml %} +second_step: + title: Second step + when: + steps: + - name: first_step + on: + - success +{% endhighlight %} + +If you want to run the second step only if the first one fails the syntax is: + +{% highlight yaml %} +second_step: + title: Second step + when: + steps: + - name: first_step + on: + - failure +{% endhighlight %} + +Finally, if you don't care about the completion status the syntax is: + +{% highlight yaml %} +second_step: + title: Second step + when: + steps: + - name: first_step + on: + - finished +{% endhighlight %} + +Notice that `success` is the default behavior so if you omit the last two lines (i.e., the `on:` part) the second step +will wait for the next step to run successfully. + +>Also notice that the name `main_clone` is reserved for the automatic clone that takes place in the beginning of pipelines that are linked to a git repository. You need to define which steps depend on it (probably the start of your graph) so that `git checkout` happens before the other steps. + +As an example, let's assume that you have the following steps in a pipeline: + +1. A build step that creates a Docker image +1. A freestyle step that runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) inside the Docker image +1. A freestyle step that runs [integrations tests]({{site.baseurl}}/docs/testing/integration-tests/) *After* the unit tests, even if they fail +1. A cleanup step that runs after unit tests if they fail + +Here is the full pipeline. Notice the explicit dependency to the `main_clone` step that checks out the code. + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +mode: parallel +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-node-js-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + when: + steps: + - name: main_clone + on: + - success + MyUnitTests: + title: Running unit tests + image: ${{MyAppDockerImage}} + fail_fast: false + commands: + - npm run test + when: + steps: + - name: MyAppDockerImage + on: + - success + MyIntegrationTests: + title: Running integration tests + image: ${{MyAppDockerImage}} + commands: + - npm run integration-test + when: + steps: + - name: MyUnitTests + on: + - finished + MyCleanupPhase: + title: Cleanup unit test results + image: alpine + commands: + - ./cleanup.sh + when: + steps: + - name: MyUnitTests + on: + - failure +{% endraw %} +{% endhighlight %} + +If you run the pipeline you will see that Codefresh automatically understands that `MyIntegrationTests` and `MyCleanupPhase` can run in parallel right after the unit tests finish. + +Also notice the `fail_fast: false` line in the unit tests. By default, if *any* steps fails in a pipeline the whole pipeline is marked as a failure. With the `fail_fast` directive we can allow the pipeline to continue so that other steps that depend on the failed step can still run even. + + +### Multiple Step dependencies + +A pipeline step can also depend on multiple other steps. + +The syntax is: + +{% highlight yaml %} +third_step: + title: Third step + when: + steps: + all: + - name: first_step + on: + - success + - name: second_step + on: + - finished +{% endhighlight %} + +In this case, the third step will run only when BOTH first and second are finished (and first is actually a success) + +*ALL* is the default behavior so it can be omitted if this is what you need. The example above +is example the same as below: + +{% highlight yaml %} +third_step: + title: Third step + when: + steps: + - name: first_step + on: + - success + - name: second_step + on: + - finished +{% endhighlight %} + +Codefresh also allows you to define *ANY* behavior in an explicit manner: + +{% highlight yaml %} +third_step: + title: Third step + when: + steps: + any: + - name: first_step + on: + - success + - name: second_step + on: + - finished +{% endhighlight %} + +Here the third step will run when either the first one *OR* the second one have finished. + +As an example let's assume this time that we have: + +1. A build step that creates a docker image +1. Unit tests that will run when the docker image is ready +1. Integration tests that run either after unit tests or if the docker image is ready (contrived example) +1. A cleanup step that runs when both kinds of tests are finished + +Here is the full pipeline + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +mode: parallel +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-node-js-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + MyUnitTests: + title: Running unit tests + image: ${{MyAppDockerImage}} + fail_fast: false + commands: + - npm run test + when: + steps: + - name: MyAppDockerImage + on: + - success + MyIntegrationTests: + title: Running integration tests + image: ${{MyAppDockerImage}} + commands: + - npm run integration-test + when: + steps: + any: + - name: MyUnitTests + on: + - finished + - name: MyAppDockerImage + on: + - success + MyCleanupPhase: + title: Cleanup unit test results + image: alpine + commands: + - ./cleanup.sh + when: + steps: + all: + - name: MyUnitTests + on: + - finished + - name: MyIntegrationTests + on: + - finished +{% endraw %} +{% endhighlight %} + +In this case Codefresh will make sure that cleanup happens only when both unit and integration tests are finished. + + +### Custom Steps Dependencies + +For maximum flexibility you can define a custom conditional for a step. + +It is hard to describe all possible cases, because Codefresh support a [mini DSL]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) for conditions. All examples mentioned in [conditional execution]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) are still valid in parallel pipelines. + +For example, run this step only if a PR is opened against the production branch: + +{% highlight yaml %} +{% raw %} +my_step: + title: My step + when: + condition: + all: + validateTargetBranch: '"${{CF_PULL_REQUEST_TARGET}}" == "production"' + validatePRAction: '''${{CF_PULL_REQUEST_ACTION}}'' == ''opened''' +{% endraw %} +{% endhighlight %} + +Run this step only for the master branch and when the commit message does not include "skip ci": + +{% highlight yaml %} +{% raw %} +my_step: + title: My step + when: + condition: + all: + noSkipCiInCommitMessage: 'includes(lower("${{CF_COMMIT_MESSAGE}}"), "skip ci") == false' + masterBranch: '"${{CF_BRANCH}}" == "master"' +{% endraw %} +{% endhighlight %} + +You can now add extra conditions regarding the completion state of specific steps. A global object called `steps` contains all steps by name along with a `result` property with the following possible completion states: + +* Success +* Failure +* Skipped (only valid in sequential mode) +* Finished (regardless of status) +* Pending +* Running + +Finished is a shorthand for `success` or `failure` or `skipped`. It is only valid when used in [step dependencies]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#single-step-dependencies), and cannot be used in custom conditions. + +You can mix and match completion states from any other step in your pipeline. Here are some examples: + +{% highlight yaml %} +my_step: + title: My step + when: + condition: + all: + myCondition: steps.MyUnitTests.result == 'failure' || steps.MyIntegrationTests.result == 'failure' +{% endhighlight %} + +{% highlight yaml %} +my_step: + title: My step + when: + condition: + any: + myCondition: steps.MyLoadTesting.result == 'success' + myOtherCondition: steps.MyCleanupStep.result == 'success' +{% endhighlight %} + +You can also use conditions in the success criteria for a parallel step. Here is an example + +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- start +- tests +- cleanup +steps: + MyAppDockerImage: + stage: 'start' + title: Building Docker Image + type: build + image_name: my-full-stack-app + working_directory: ./01_sequential/ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + MyTestingPhases: + type: parallel + stage: 'tests' + success_criteria: + condition: + all: + myCondition: ${{steps.my_back_end_tests.result}} === 'success' && ${{steps.my_front_end_tests.result}} === 'success' + steps: + my_back_end_tests: + title: Running Back end tests + image: ${{MyAppDockerImage}} + commands: + - exit 1 + my_front_end_tests: + title: Running Front End tests + image: ${{MyAppDockerImage}} + commands: + - echo "Second" + MyCleanupPhase: + stage: 'cleanup' + title: Cleanup unit test results + image: alpine + commands: + - echo "Finished" +{% endraw %} +{% endhighlight %} + + +## Handling error conditions in a pipeline + +It is important to understand the capabilities offered by Codefresh when it comes to error handling. You have several options in different levels of granularity to select what constitutes a failure and what not. + +By default, *any* failed step in a pipeline will abort the whole pipeline and mark it as failure. + +You can use the directive `fail_fast: false`: +* In a specific step to mark it as ignored if it fails +* At the root level of the pipeline if you want to apply it to all steps + +Therefore, if you want your pipeline to keep running to completion regardless of errors the following syntax is possible: + +``` +version: '1.0' +fail_fast: false +steps: +[...] +``` + +You also have the capability to define special steps that will run when the whole pipeline has a special completion status. Codefresh offers a special object called `workflow` that represents the whole pipeline and allows you to evaluate its status in a step. + +For example, you can have a cleanup step that will run only if the workflow fails (regardless of the actual step that created the error) with the following syntax: + +{% highlight yaml %} +my_cleanup_step: + title: My Pipeline Cleanup + when: + condition: + all: + myCondition: workflow.result == 'failure' +{% endhighlight %} + +As another example we have a special step that will send an email if the pipeline succeeds or if load-tests fail: + +{% highlight yaml %} +my_email_step: + title: My Email step + when: + condition: + any: + myCondition: workflow.result == 'success' + myTestCondition: steps.MyLoadTesting.result == 'failure' +{% endhighlight %} + +Notice that both examples assume that `fail_fast: false` is at the root of the `codefresh.yaml` file. + +The possible values for `workflow.result` are: + +* `running` +* `terminated` +* `failure` +* `pending-approval` +* `success` + + +## What to read next + +* [Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) +* [Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) + + + + + + + + diff --git a/_docs/pipelines/annotations.md b/_docs/pipelines/annotations.md new file mode 100644 index 00000000..58886a6e --- /dev/null +++ b/_docs/pipelines/annotations.md @@ -0,0 +1,303 @@ +--- +title: "Annotations" +description: "Mark your builds and projects with extra annotations" +group: codefresh-yaml +toc: true +--- + +Codefresh supports the annotations of several entities with custom annotations. You can use these annotations to store any optional information that you wish to keep associated with each entity. Examples would be storing the test coverage for a particular build, or a special settings file for a pipeline. + +Currently Codefresh supports extra annotations for: + +* Projects +* Pipelines +* Builds +* Docker images + +You can view/edit annotations using the [Codefresh CLI](https://codefresh-io.github.io/cli/annotations/) or directly in the Codefresh Web UI. + +>Notice that the syntax shown in this page is deprecated but still supported. For the new syntax +see our [hooks documentation]({{site.baseurl}}/docs/codefresh-yaml/hooks/). + + +## Adding annotations + +In the most basic scenario you can use the [post operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) of any Codefresh [step]({{site.baseurl}}/docs/codefresh-yaml/steps/) to add annotations: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_custom_step: + title: Adding annotations to a project + image: alpine:3.9 + commands: + - echo "Hello" + on_success: + annotations: + set: + - entity_id: annotate-examples + entity_type: project + annotations: + - my_annotation_example1: 10.45 + - my_empty_annotation + - my_string_annotation: Hello World +{% endraw %} +{% endhighlight %} + + +This pipeline adds three annotations to a project called `annotate-examples`. The name of each annotation can only contain letters (upper and lowercase), numbers and the underscore character. The name of each annotation must start with a letter. + + +For the `entity_id` value you can also use an actual ID instead of a name. The `entity_id` and `entity_type` are define which entity will hold the annotations. The possible entity types are: + +* `project` (for a project, even a different one) +* `pipeline` (for a pipeline, even a different one) +* `build` (for a build, even a different one) +* `image` (for a docker image) + +If you don't define them, then by default the current build will be used with these values: +* `entity_id` is `{% raw %}${{CF_BUILD_ID}}{% endraw %}` (i.e. the current build) +* `entity_type` is `build` + +Here is another example where we add annotations to another pipeline as well as another build (instead of the current one) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_custom_step: + title: Adding annotations to multiple entities + image: alpine:3.9 + commands: + - echo "Hello" + on_success: + annotations: + set: + - entity_id: my-project/my-basic-pipeline + entity_type: pipeline + annotations: + - my_annotation_example1: 10.45 + - my_empty_annotation + - my_string_annotation: Hello World + - entity_id: 5ce2a0e869e2ed0a60c1e203 + entity_type: build + annotations: + - my_coverage: 70 + - my_url_example: http://www.example.com +{% endraw %} +{% endhighlight %} + +It is therefore possible to store annotations on any Codefresh entity (and not just the ones that are connected to the build that is adding annotations). + +## Viewing/Editing annotations + +You can view the annotations using the Codefresh CLI + +```shell +codefresh get annotation project annotate-examples +``` + +You can also view annotations within the Codefresh UI. + +For build annotations click the *Annotations* on the build details: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/annotations/view-build-annotations.png" +url="/images/codefresh-yaml/annotations/view-build-annotations.png" +alt="Viewing Build annotations" +caption="Viewing Build annotations" +max-width="80%" +%} + +For pipeline annotations click the *Annotations* button in the pipeline list view: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/annotations/view-pipeline-annotations.png" +url="/images/codefresh-yaml/annotations/view-pipeline-annotations.png" +alt="Viewing Pipeline annotations" +caption="Viewing Pipeline annotations" +max-width="80%" +%} + +For project annotations click the *Annotations* button in the project list view: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/annotations/view-project-annotations.png" +file="/images/codefresh-yaml/annotations/view-project-annotations.png" +url="/images/codefresh-yaml/annotations/view-build-annotations.png" +alt="Viewing project annotations" +caption="Viewing project annotations" +max-width="80%" +%} + +In all cases you will see a dialog with all existing annotations. + + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/annotations/edit-project-annotations.png" +url="/images/codefresh-yaml/annotations/edit-project-annotations.png" +alt="Editing annotations" +caption="Editing annotations" +max-width="50%" +%} + +You can add additional annotations manually by clicking the *Add annotation* button and entering: + +* The name of the annotation +* The type of the annotation (text, number, percentage, link, boolean) +* The desired value + +Click *Save* to apply your changes. + +## Complex annotation values + +Apart from scalar values, you can also store more complex expressions in annotations. You have access to all [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/), text files from the build and even evaluations from the [expression syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'kostis-codefresh/nestjs-example' + revision: '${{CF_REVISION}}' + my_custom_step: + title: Complex annotations + image: alpine:3.9 + commands: + - echo "Hello" + - echo "Sample content" > /tmp/my-file.txt + on_finish: + annotations: + set: + - entity_id: annotate-examples/simple + entity_type: pipeline + annotations: + - qa: pending + - commit_message: ${{CF_COMMIT_MESSAGE}} + - is_main_branch: + evaluate: "'${{CF_BRANCH}}' == 'main'" + - my_json_file: "file:/tmp/my-file.txt" + - my_docker_file: "file:Dockerfile" +{% endraw %} +{% endhighlight %} + +>Notice that this pipeline is using dynamic git repository variables, so it must be linked to a least one [git trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) in order to work. + +The last two annotations add the text of a file as a value. You can define an absolute or relative path. No processing is done on the file before being stored. If a file is not found, the annotation will still be added verbatim. +We suggest you only store small text files in this manner as annotations values. + +## Removing annotations + +You can also remove annotations by mentioning their name: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_custom_step: + title: Adding annotations to a pipeline + image: alpine:3.9 + commands: + - echo "Hello" + on_success: + annotations: + set: + - entity_id: my-project/my-basic-pipeline + entity_type: pipeline + annotations: + - my_annotation_example1: 10.45 + - my_empty_annotation + - my_string_annotation: Hello World + - my_second_annotation: This one will stay + my_unit_tests: + title: Removing annotations + image: alpine:3.9 + commands: + - echo "Tests failed" + - exit 1 + on_fail: + annotations: + unset: + - entity_id: my-project/my-basic-pipeline + entity_type: pipeline + annotations: + - my_annotation_example1 + - my_empty_annotation + - my_string_annotation +{% endraw %} +{% endhighlight %} + +You can also use both `unset` and `set` block in a single `annotations` block. And of course, you can remove annotations from multiple entities. + +The `unset` annotation can be used with all post-step operations (`on_success`, `on_fail`, `on_finish`). + + +## Adding annotations to the current build/image + +As a convenience feature: + +1. If your pipeline has a build step +1. If you want to add annotations to the present build or image + +you can also define annotations in the root level of the build step and not mention the entity id and type. Annotations will then be added in the present build. + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'kostis-codefresh/nestjs-example' + revision: 'master' + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-app-image + working_directory: ./ + tag: 'sample' + dockerfile: Dockerfile + annotations: + set: + - annotations: + - my_number_annotation: 9999 + - my_empty_annotation + - my_docker_file: "file:Dockerfile" + - my_text_annotation: simple_text +{% endraw %} +{% endhighlight %} + +After running this pipeline at least once, you can retrieve the annotations from any previous build by using the respective id: + +```shell +codefresh get annotation build 5ce26f5ff2ed0edd561fa2fc +``` + +You can also define `entity_type` as `image` and don't enter any `entity_id`. In this case the image created from the build step will be annotated. + + +Note that this syntax is optional. You can still define annotations for a build/image or any other entity using the post operations of any step by mentioning explicitly the target id and type. + +## What to read next + +* [Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) +* [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) diff --git a/_docs/pipelines/build-status.md b/_docs/pipelines/build-status.md new file mode 100644 index 00000000..05a0ef40 --- /dev/null +++ b/_docs/pipelines/build-status.md @@ -0,0 +1,151 @@ +--- +title: "Public logs and status badges" +description: "Embedding Status Images and viewing public logs" +group: configure-ci-cd-pipeline +toc: true +redirect_from: + - /docs/build-status + - /docs/build-status/ + - /docs/build-badges-1 + - /docs/build-badges-1/ +--- + + +Badges are simple images that show you the last build status. They support both the pipeline and branch service status. +The badges can be embedded into your repository’s `readme.md` file or any other website. + +Here is an example: + +{% include +image.html +lightbox="true" +file="/images/pipeline/badges/badge.png" +url="/images/pipeline/badges/badge.png" +alt="Build badge example" +caption="Build badge example" +max-width="80%" +%} + +Clicking the badge takes you into the build view of the pipeline. + +## Finding the build badge of your project + +In the pipeline view of a project, select the *Settings* tab and then click *General*. Next to the *badges* section you will find a link to the build badge. + +{% include +image.html +lightbox="true" +file="/images/pipeline/badges/get-build-badge.png" +url="/images/pipeline/badges/get-build-badge.png" +alt="Build badge setup" +caption="Build badge setup" +max-width="80%" +%} + +Click on it and you will get a new dialog where you can select + + * The graphical style of the badge (two styles are offered) + * The syntax for the badge + +{% include + image.html + lightbox="true" + file="/images/a0c4aed-codefresh_badges_2.png" + url="/images/a0c4aed-codefresh_badges_2.png" + alt="Codefresh badges syntax" + caption="Codefresh badges syntax" + max-width="70%" + %} + + The following embedding options are available: + + * Markdown for usage in text files (e.g. `README.MD`) + * Plain HTML for normal websites + * AsciiDoc for documentation pages + * Image for any other document type + + +Copy the snippet in your clipboard. + +## Using the build badge + +Paste the snippet in the file/document where you want the badge to be visible (e.g. in a Readme file in GitHub). + +For example, the markdown syntax is + +``` +[![Codefresh build status]( BADGE_LINK )]( URL_TO_PIPELINE ) +``` + +You can also manually change the parameters of the link by using +`https://g.codefresh.io/api/badges/build?*param1*=xxx&*param2*=yyy`\\ +when *param1*, *param2*, etc... are the parameters from the table below. + +{: .table .table-bordered .table-hover} +| Query parameter | Description | +| -----------------------|--------------------------------------------------------- | +| **branch** - optional | Name of the branch
If not supplied, default is master | +| **repoName** | Name of the repository | +| **pipelineName** | Name of the pipeline | +| **accountName** | Name of the account | +| **repoOwner** | The name of the repository owner | +| **key** - optional | Token related to the account | +| **type** - optional | Badge types
cf-1: ![Codefresh build status]( http://g.codefresh.io/api/badges/build/template/urls/cf-1) - also the default badge.
cf-2: ![Codefresh build status]( http://g.codefresh.io/api/badges/build/template/urls/cf-2) | + +Everybody who looks at your readme file will also see the current build status of the associated Codefresh pipeline. + +## Public build logs + +By default, even though the badge shows the build status for everybody, clicking the badge allows only Codefresh registered users that also have access to the pipeline to view the actual builds. + +If you are working on an open-source project and wish for greater visibility, you can enable public logs (and associated badge) for your project so that any user can see the pipeline results (even if they are not logged into Codefresh). + +Public logs are disabled by default and you need to explicitly enable them. + +>This happens for security reasons. Make sure that the logs you are exposing to the Internet do not have any sensitive information. If you are unsure, you can still use the private badge that shows project status only as explained in the previous section. + +To enable the public logs, toggle the respective switch in the pipeline settings: + +{% include +image.html +lightbox="true" +file="/images/pipeline/badges/toggle-public-logs.png" +url="/images/pipeline/badges/toggle-public-logs.png" +alt="Enabling public logs" +caption="Enabling public logs" +max-width="80%" +%} + +Then click the *Save* button to apply changes for your pipeline. Once that is done you will also get a second badge (public) as well as the public URL to your project. + +{% include +image.html +lightbox="true" +file="/images/pipeline/badges/get-public-url.png" +url="/images/pipeline/badges/get-public-url.png" +alt="Getting the public URL log view" +caption="Getting the public URL log view" +max-width="70%" +%} + +Now you can use this badge and/or public URL anywhere and all users can view your logs without being logged into Codefresh at all (or having access to your pipeline). + +{% include +image.html +lightbox="true" +file="/images/pipeline/badges/view-public-logs.png" +url="/images/pipeline/badges/view-public-logs.png" +alt="Public logs" +caption="Public logs" +max-width="90%" +%} + +Your visitors can also click on each individual pipeline step and see the logs for that step only. + +If you are using Codefresh to manage a public project, you should also use the capability to [trigger builds from external forks]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/#support-for-building-pull-requests-from-forks). + +## What to read next + +* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Monitoring pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/) diff --git a/_docs/pipelines/condition-expression-syntax.md b/_docs/pipelines/condition-expression-syntax.md new file mode 100644 index 00000000..4fd3e774 --- /dev/null +++ b/_docs/pipelines/condition-expression-syntax.md @@ -0,0 +1,107 @@ +--- +title: "Condition Expression Syntax" +description: "Condition expressions can be included in each step in your codefresh.yml, and must be satisfied for the step to execute." +group: codefresh-yaml +redirect_from: + - /docs/condition-expression-syntax/ + - /docs/codefresh-yaml/expression-condition-syntax/ +toc: true +--- +Each step in `codefresh.yml` file can contain conditions expressions that must be satisfied for the step to execute. + +This is a small example of where a condition expression can be used: + `YAML` +{% highlight yaml %} +step-name: + description: Step description + image: image/id + commands: + - bash-command1 + - bash-command2 + when: + condition: + all: + executeForMasterBranch: "{% raw %}'${{CF_BRANCH}}{% endraw %}' == 'master'" +{% endhighlight %} + +A condition expression is a basic expression that is evaluated to true/false (to decide whether to execute or not to execute), and can have the following syntax: + +### Types + +{: .table .table-bordered .table-hover} +| Type | True/False Examples | True/False | +| ------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| String | True: "hello"
False: "" | {::nomarkdown}String comparison is lexicographic.{:/} | +| Number | True: 5
True: 3.4
True: 1.79E+308 | {::nomarkdown}{:/} | +| Boolean | True: true
False: false | {::nomarkdown}{:/} | +| Null | False: null | Always false | + +### Variables + +You can use the User Provided variables as explained in the [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) documentation including the [variables +exposed by each individual pipeline step]({{site.baseurl}}/docs/codefresh-yaml/variables/#step-variables). + +### Unary Operators + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| ---------- | --------------------- | +| `-` | Negation of numbers | +| `!` | Logical NOT | + +### Binary Operators + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| --------------------------- | ----------- | +| Add, String Concatenation | `+` | +| Subtract | `-` | +| Multiply | `*` | +| Divide | `/` | +| Modulus | `%` | +| Logical AND | `&&` | +| Logical OR | `||` | + +### Comparisons + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| ----------- | ---------------------- | +| `==` | Equal to | +| `!=` | Not equal to | +| `>` | Greater than | +| `>=` | Greater than or equal | +| `<` | Less than | +| `<=` | Less than or equal | + +### Functions + +{: .table .table-bordered .table-hover} +| Function Name | Parameters | Return value | Example | +| ------------- | ------------------ | -------------- | ----------------------- | +| String | 0: number or string | String of input value. | `String(40) == '40'` | +| Number | 0: number or string | Number of input value. | `Number('50') == 50`
`Number('hello')` is invalid | +| Boolean | 0: number or string | Boolean of input value. | `Boolean('123') == true`
`Boolean('') == false`
`Boolean(583) == true`
`Boolean(0) == false` | +| round | 0: number | Rounded number. | `round(1.3) == 1`
`round(1.95) == 2` | +| floor | 0: number | Number rounded to floor. | `floor(1.3) == 1`
`floor(1.95) == 1` | +| upper | 0: string | String in upper case. | `upper('hello') == 'HELLO'` | +| lower | 0: string | String in lower case. | `lower('BYE BYE') == 'bye bye'` | +| trim | 0: string | Trimmed string. | `trim(" abc ") == "abc"` | +| trimLeft | 0: string | Left-trimmed string. | `trimLeft(" abc ") == "abc "` | +| trimRight | 0: string | Right-trimmed string. | `trimRight(" abc ") == " abc"` | +| replace | 0: string - main string
1: string - substring to find
2: string - substring to replace | Replace all instances of the sub-string (1) in the main string (0) with the sub-string (2). | `replace('hello there', 'e', 'a') == 'hallo thara'` | +| substring | 0: string - main string
1: string - index to start
2: string - index to end | Returns a sub-string of a string. | `substring("hello world", 6, 11) == "world"` | +| length | string | Length of a string. | `length("gump") == 4` | +| includes | 0: string - main string
1: string - string to search for | Whether a search string is located within the main string. | `includes("codefresh", "odef") == true` | +| indexOf | 0: string - main string
1: string - string to search for | Index of a search string if it is found inside the main string | `indexOf("codefresh", "odef") == 1` | +| match | 0: string - main string
1: string - regular expression string, [JS style](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) (Note: in JS strings, the backslash `\` is an escape character so in order to use a literal backslash, you need to escape it. For example: `"^\\d+$"` instead of `"^\d+$"`)
2: boolean - ignore case | Search for a regular expression inside a string, ignoring or not ignoring case | `match("hello there you", "..ll.", false) == true`
`match("hello there you", "..LL.", false) == false`
`match("hello there you", "hell$", true) == false`
`match("hello there you", "^hell", true) == true`
`match("hello there you", "bye", false) == false` | +| Variable | string | Search for the value of a variable | `Variable('some-clone')` | +| Member | 0: string - variable name
1: string - member name | Search for the value of a variable member | `Member('some-clone', 'working-directory')` | + +## What to read next + +* [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +* [Condition Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +* [Working Directories]({{site.baseurl}}/docs/codefresh-yaml/working-directories/) +* [Annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) diff --git a/_docs/pipelines/conditional-execution-of-steps.md b/_docs/pipelines/conditional-execution-of-steps.md new file mode 100644 index 00000000..56eea7d7 --- /dev/null +++ b/_docs/pipelines/conditional-execution-of-steps.md @@ -0,0 +1,155 @@ +--- +title: "Conditional Execution of Steps" +description: "Skip specific pipeline steps according to one or more conditions" +group: codefresh-yaml +redirect_from: + - /docs/conditional-execution-of-steps/ +toc: true +--- +For each step in a `codefresh.yml` file, you can define a set of conditions which need to be satisfied in order to execute the step. (An introduction to the `codefresh.yml` file can be found [here]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/).) + +There are currently two main methods to define conditions: branch conditions and expression conditions. + +## Branch Conditions + +Usually, you'll want to define a branch condition, be it of the type ```ignore``` for blacklisting a set of branches or of the type ```only``` for allowlisting a set of branches. Each branch specification can either be an exact branch name, e.g. ```master```, or a regular expression, e.g. ```/hotfix$/```. Case insensitive regexps (```/^FB-/i```) are also supported. + +Here are some examples: + +Only execute for the ```master``` branch: + + `only-master-branch.yml` +{% highlight yaml %} +build-step: + description: Building the image. + type: build + dockerfile: Dockerfile + image-name: someRepo/someUser + when: + branch: + only: + - master +{% endhighlight %} + +Only execute for branches whose name begins with ```FB-``` prefix (feature branches): + + `only-feature-branches.yml` +{% highlight yaml %} +build-step: + description: Building the image. + type: build + dockerfile: Dockerfile + image-name: someRepo/someUser + when: + branch: + only: + - /^FB-.*/i +{% endhighlight %} + +Ignore the develop branch and master branch: + + `ignore-master-and-develop-branch.yml` +{% highlight yaml %} +build-step: + description: Building the image. + type: build + dockerfile: Dockerfile + image-name: someRepo/someUser + when: + branch: + ignore: + - master + - develop +{% endhighlight %} + + +>We use [JavaScript regular expressions](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions) for the syntax in branch conditions. + + +## Condition expressions + +Alternatively, you can use more advanced condition expressions. + +This follows the standard [condition expression syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/). In this case, you can choose to execute if ```all``` expression conditions evaluate to ```true```, or to execute if ```any``` expression conditions evaluate to ```true```. + +> Note: Use "" around variables with text to avoid errors in processing the conditions. ex: "${{CF_COMMIT_MESSAGE}}" + +Here are some examples. Execute if the string ```[skip ci]``` is not part of the main repository commit message AND if the branch is ```master``` + + `all-conditions.yml` +{% highlight yaml %} +build-step: + description: Building the image. + type: build + dockerfile: Dockerfile + image-name: someRepo/someUser + when: + condition: + all: + noSkipCiInCommitMessage: 'includes(lower({% raw %}"${{CF_COMMIT_MESSAGE}}"{% endraw %}), "skip ci") == false' + masterBranch: '{% raw %}"${{CF_BRANCH}}{% endraw %}" == "master"' +{% endhighlight %} + +Execute if the string ```[skip ci]``` is not part of the main repository commit message, OR if the branch is not a feature branch (i.e. name starts with FB-) + + `any-condition.yml` +{% highlight yaml %} +build-step: + description: Building the image. + type: build + dockerfile: Dockerfile + image-name: someRepo/someUser + when: + condition: + any: + noSkipCiInCommitMessage: 'includes(lower({% raw %}"${{CF_COMMIT_MESSAGE}}"{% endraw %}), "skip ci") == false' + notFeatureBranch: 'match({% raw %}"${{CF_BRANCH}}"{% endraw %}, "^FB-", true) == false' +{% endhighlight %} + +## Execute steps according to the presence of a variable + +If a variable does not exist in a Codefresh pipeline, then it will simply stay as a string inside the definition. When the `{% raw %}${{MY_VAR}}{% endraw %}` variable is not available, the engine will literally print `{% raw %}${{MY_VAR}}{% endraw %}`, because that variable doesn't exist. + +You can use this mechanism to decide which steps will be executed if a [variable]({{site.baseurl}}/docs/codefresh-yaml/variables/) exists or not. + + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + step1: + title: "Running if variable exists" + type: "freestyle" + image: "alpine:3.9" + commands: + - echo "Step 1 is running" + when: + condition: + all: + whenVarExists: 'includes("${{MY_VAR}}", "{{MY_VAR}}") == false' + step2: + title: "Running if variable does not exist" + type: "freestyle" + image: "alpine:3.9" + commands: + - echo "Step 2 is running" + when: + condition: + all: + whenVarIsMissing: 'includes("${{MY_VAR}}", "{{MY_VAR}}") == true' +{% endraw %} +{% endhighlight %} + +Try running the pipeline above and see how it behaves when a variable called `MY_VAR` exists (or doesn't exist). + +>Notice that if you use this pattern a lot it means that you are trying to create a complex pipeline that is very smart. We suggest you create instead multiple [simple pipelines for the same project]({{site.baseurl}}/docs/ci-cd-guides/pull-request-branches/#trunk-based-development). + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) +* [Condition syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +* [Pull Requests and Branches]({{site.baseurl}}/docs/ci-cd-guides/pull-request-branches/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) diff --git a/_docs/pipelines/debugging-pipelines.md b/_docs/pipelines/debugging-pipelines.md new file mode 100644 index 00000000..90b36301 --- /dev/null +++ b/_docs/pipelines/debugging-pipelines.md @@ -0,0 +1,257 @@ +--- +title: "Debugging Codefresh pipelines" +description: "How to pause and inspect pipelines" +group: configure-ci-cd-pipeline +toc: true +--- + +In addition to [running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) Codefresh also allows you to debug pipelines by stopping their execution and inspecting manually their state (files, environment variables, tools etc.) + +## How Debugging works + +The Codefresh pipeline debugger works similar to your IDE debugger. You can place breakpoints on one or more pipeline steps and once the pipeline hits one of them, it will stop. You will then get a terminal like interface inside your pipeline step where you can run any commands that you wish in order to understand the state of the container. + + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/debug-session.png" + url="/images/pipeline/debug/debug-session.png" + alt="A debugging session" + caption="A debugging session" + max-width="70%" +%} + +There are several option for defining exactly when a step will stop. + +## Entering the debugger mode + +There are threes ways to enter the debugging mode in a pipeline. You can activate the debugging button when your run the pipeline: + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/run-pipeline-debug.png" + url="/images/pipeline/debug/run-pipeline-debug.png" + alt="Running a pipeline in debug mode" + caption="Running a pipeline in debug mode" + max-width="30%" +%} + +Alternatively if a pipeline is already running normally, you can enter debugging mode by clicking on the bug icon on the top right. + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/enter-debug-mode.png" + url="/images/pipeline/debug/enter-debug-mode.png" + alt="Switching to debug mode" + caption="Switching to debug mode" + max-width="60%" +%} + +You can restart a pipeline that has already finished in debug mode: + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/restart-in-debug.png" + url="/images/pipeline/debug/restart-in-debug.png" + alt="Restart in debug mode" + caption="Restart in debug mode" + max-width="70%" +%} + +Now you are ready to place breakpoints in steps. + + +## Placing breakpoints + +Once the debugging mode is active all pipeline steps will get an extra breakpoint icon on the far right of their box. + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/breakpoint.png" + url="/images/pipeline/debug/breakpoint.png" + alt="A step breakpoint" + caption="A step breakpoint" + max-width="70%" +%} + + +You can click on this icon and define a breakpoint for this particular step. You have the following options + +* *Before* - place a breakpoint before the step is initialized +* *Override* - place a breakpoint after the step has initialized but before its execution ([freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/)) +* *After* - place a breaking point after the step has finished execution. + +You can choose multiple debugging phases. In most cases the `Override` option is the most useful one. The `before` phase allows you to inspect +a pipeline step even before [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) are up. + +The `after` phase is useful if you want to verify files or variables after a step has finished its execution but before the next step starts. + + +## Using the debugger terminal + +Once the pipeline reaches a step that has a breakpoint, execution will pause and a new debugger terminal will become available: + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/debug-window.png" + url="/images/pipeline/debug/debug-window.png" + alt="The debugging terminal" + caption="The debugging terminal" + max-width="60%" +%} + +You can now manually type commands to inspect your container. If your Codefresh plan has the basic debugging capabilities you can run the following commands: + +* `cd, ls` to see files +* `printenv` to see environment variables +* `cat` to read files +* `top` to see what is running +* `export` and [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) to create environment variables +* `exit` to finish the debugging session + +If you have placed a breakpoint in the `override` phase of a freestyle step then the container image is the same as the one defined in the step. Therefore you can execute all tools that you have placed in the image (e.g. compilers, linters, test frameworks etc.) + +In all cases the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automounted so you can examine your source code or any other intermediate artifacts placed in your project folder or the pipeline cache. + +If the breakpoint is on a `before` or `after` phase, the command line terminal is powered by an [alpine](https://alpinelinux.org/) image. The image has already useful tools such as `wget`, `nc` and `vi`. If you have the advanced debugging capabilities in your Codefresh plan you can then install additional tools on your own directly in the terminal with [apk](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management). Examples: + +* `apk add curl` +* `apk add nano` +* `apk add go` +* `apk add python` + +Use the command `apk search foo` to search for a package named foo. + + +## Resuming execution + +Once you are happy with your debugging session, click the continue button to resume. + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/resume-button.png" + url="/images/pipeline/debug/resume-button.png" + alt="Continue execution button" + caption="Continue execution button" + max-width="60%" +%} + +The pipeline will continue and then stop for the next breakpoint (if any). You can still revisit the debugger window for previous steps to see what debugging commands you had executed. + +>Notice that to conserve resources, there is a 15 minute limit on each open debug session. If you don't resume the pipeline within 15 minutes after hitting a breakpoint the whole pipeline will stop with a timeout error. + +It is important to understand that if you have chosen the `override` phase in a freestyle step, then the commands mentioned in the pipeline definition are completely ignored. + +## Using the alternative debug window + +If you enable the debugger on a freestyle step with the "override" option, Codefresh will install some extra tooling on the Docker image that is needed for the debugger itself. + +By default, the internal debugger tooling is using node.js, so if your image is already based on Node.js, you might get version conflicts in your application. + +You can enable an alternative debugger by passing the variable `DEBUGGER_RUNNER = 2` on the whole pipeline: + +{% + include image.html + lightbox="true" + file="/images/pipeline/debug/alternative-debugger.png" + url="/images/pipeline/debug/alternative-debugger.png" + alt="Enabling the Python based debugger" + caption="Enabling the Python based debugger" + max-width="60%" +%} + +This debugger is based on Python instead of Node.js and it can work with both Python 2 and 3 Docker images. +This way the debugger tools will not affect your application. You can also use the same method in a specific freestyle step like this: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + hello_world_step: + title: freestyle step + image: node:11.1 + environment: + - 'DEBUGGER_RUNNER=2' +{% endraw %} +{% endhighlight %} + + + + + +## Inserting breakpoints in the pipeline definition + +It is also possible to mention breakpoints in the Codefresh YAML instead of using the UI. Breakpoints mentioned in the `codefresh.yml` file have no effect when the pipeline is not running in Debug mode. You need to run the pipeline in debug mode in order for them to stop the pipeline. + +Here is the syntax: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - test +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/python-flask-sample-app' + revision: 'master' + git: github + stage: prepare + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: my-app-image + working_directory: ./ + tag: 'master' + dockerfile: Dockerfile + debug: + phases: + before: true + after: false + MyUnitTests: + title: Running Unit tests + stage: test + image: '${{MyAppDockerImage}}' + debug: + phases: + before: false + override: true + after: false + commands: + - python setup.py test +{% endraw %} +{% endhighlight %} + +Once you run this pipeline in debug mode, it will automatically have breakpoints in the respective steps (but you can still override/change them using the GUI). + + +## Troubleshooting + +The debugger windows needs some extra tools in a docker image in order to work (such as the `bash` shell). Codefresh automatically installs these tools on your image without any configuration. + +If you get the message *your linux distribution is not supported* please contact us so that we can examine your docker image and make sure it is compatible with the Codefresh debugger. + + + + + + +## What to read next + +* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) diff --git a/_docs/pipelines/docker-image-metadata.md b/_docs/pipelines/docker-image-metadata.md new file mode 100644 index 00000000..061e0f0f --- /dev/null +++ b/_docs/pipelines/docker-image-metadata.md @@ -0,0 +1,219 @@ +--- +title: "Docker image Metadata" +description: "How to use custom metadata in your Docker images" +group: codefresh-yaml +redirect_from: + - /docs/metadata-annotations/ + - /docs/docker-registries/metadata-annotations/ +toc: true +--- +Images built by Codefresh can be annotated with customized metadata. +This article explains how to create advanced view of your images and enrich them with custom metadata which perfectly fits your flow and image management process. + +{% + include image.html + lightbox="true" + file="/images/codefresh-yaml/docker-image-metadata/metadata.png" + url="/images/codefresh-yaml/docker-image-metadata/metadata.png" + alt="Codefresh Docker registry metadata" + max-width="65%" +%} + +>We have since expanded this feature and now you are able to add custom annotations to [pipelines and builds as well]({{site.baseurl}}/docs/codefresh-yaml/annotations/). Notice also that the syntax shown in this page is deprecated but still supported. For the new syntax +see our [hooks documentation]({{site.baseurl}}/docs/codefresh-yaml/hooks/). + +## Metadata types + +Images built by Codefresh can be annotated with an array of key-value metadata. +Metadata values may be of the following types: + +{: .table .table-bordered .table-hover} +| Annotation type | Guidelines | Example | +| --------------- | ------------------------------------------------ | -------------------------------------------------------- | +| String | Use string | 'Example note' | +| Number | use numeric value to set this kind of annotation | 9999 | +| Boolean | Use true / false value | true | +| Percentage bar | use 0-100 value ending with % | 85% | +| Link | use url | {% raw %}`${{CF_COMMIT_URL}}`{% endraw %} | + +You can also use [Expression evaluations]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) to set metadata. + +## Annotate your images using Codefresh YAML +You can annotate an image as part of it's builds process and also on post build steps. + +{:.text-secondary} +### Build step Image Metadata Annotation +You can annotate an image as part of its build process by declaring the metadata value on the [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/): +1. The `metadata` attribute +2. The `set` operation +3. An array of key-value metadata + + `build-metadata-annotation` +{% highlight yaml %} +build_step: + type: build + ... + metadata: # Declare the metadata attribute + set: # Specify the set operation + - qa: pending + - commit_message: {% raw %}${{CF_COMMIT_MESSAGE}}{% endraw %} + - exit_code: 0 + - is_main: + evaluate: "{% raw %}'${{CF_BRANCH}}{% endraw %}' == 'main'" +{% endhighlight %} + +{:.text-secondary} +### Adding annotations to Built images on post-build steps +Any step in the YAML workflow can annotate built images by using [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). +To annotate a built image, configure any step with: +1. The post-step operation +2. The `metadata` attribute +3. The `set` operation +4. A list of target images with the variable syntax of {% raw %}`${{build_step_name.imageId}}`{% endraw %} +5. An array of key-value metadata + + `annotating-step` +{% highlight yaml %} +build_step: + type: build + ... + +any_step: + ... + on_success: # Execute only once the step succeeded + metadata: # Declare the metadata attribute + set: # Specify the set operation + - {% raw %}${{build_step.imageId}}{% endraw %}: # Select any number of target images + - qa: pending + + on_fail: # Execute only once the step failed + metadata: # Declare the metadata attribute + set: # Specify the set operation + - {% raw %}${{build_step.imageId}}{% endraw %}: # Select any number of target images + - exit_code: 1 + + on_finish: # Execute in any case + metadata: # Declare the metadata attribute + set: # Specify the set operation + - {% raw %}${{build_step.imageId}}{% endraw %}: # Select any number of target images + - is_main: + evaluate: "{% raw %}'${{CF_BRANCH}}'{% endraw %} == 'main'" +{% endhighlight %} + +### Example - Quality Image Metadata Annotation +You can set a quality indicator to images to show if they passed or failed tests. An image with the boolean annotation `CF_QUALITY` set to true will have a quality indicator in the 'Images' view. + + `YAML` +{% highlight yaml %} +version: '1.0' +steps: + build_step: + type: build + image_name: myrepo/imagename + working_directory: ./ + dockerfile: Dockerfile + + unit_test: + image: {% raw %}'${{build_step}}'{% endraw %} + working_directory: IMAGE_WORK_DIR + commands: + - echo test + on_success: + metadata: + set: + - {% raw %}'${{build_step.imageId}}'{% endraw %}: + - CF_QUALITY: true + on_fail: + metadata: + set: + - {% raw %}'${{build_step.imageId}}'{% endraw %}: + - CF_QUALITY: false +{% endhighlight %} + +Image quality has 3 indicators: +* True - this image is considered a quality image (ex. passed tests), +* False - this image is not considered a quality image (ex. when tests failed but the image was already built). +* No value (nobody set the annotation) - this image has no quality indicator. + +{% include image.html lightbox="true" file="/images/c39a9a2-QUALI.png" url="/images/c39a9a2-QUALI.png" alt="QUALI" max-width="40%" %} + + +## Viewing Image Metadata Annotations +You can view an image's metadata annotation by: +1. Navigating to the `Images` view +2. Selecting the target image +3. Selecting the `Annotations` tab + +{% + include image.html + lightbox="true" + file="/images/codefresh-yaml/docker-image-metadata/annotations.png" + url="/images/codefresh-yaml/docker-image-metadata/annotations.png" + alt="Image annotations" + max-width="65%" +%} + +In addition, you can add selected annotations to the images table on images page. To display an annotation in the image table, click on the gear icon at the top right corner of image page and then select all annotations you want to display. + +{% include image.html lightbox="true" file="/images/aec92e8-Screen_Shot_2017-10-17_at_3.01.26_PM.png" url="/images/aec92e8-Screen_Shot_2017-10-17_at_3.01.26_PM.png" alt="Screen Shot 2017-10-08 at 8.28.35 AM.png" max-width="40%" %} + + +## Annotating images programmatically + +It is also possible to annotate images with the [Codefresh CLI](https://codefresh-io.github.io/cli/). + +First find the id of an image that you wish to annotate with the command + +``` +codefresh get images +``` + +You can also search for a specific image by name: + +``` +$ codefresh get images --image-name custom +ID NAME TAG CREATED SIZE PULL +b5f103a87856 my-custom-docker-image bla Fri Feb 01 2019 91.01 MB r.cfcr.io/kostis-codefresh/my-custom-docker-image:bla +``` +Then once you have the ID of the image you can use the [annotate command](https://codefresh-io.github.io/cli/images/annotate-image/) to add extra metadata: + +``` +codefresh annotate image b5f103a87856 -l coverage=75 +``` + +## Using custom metadata in Codefresh pipelines + +You can also use the Codefresh CLI to fetch existing metadata from images. It is then very easy to extract and process specific fields with [yq](https://github.com/kislyuk/yq) + +Here is an example +``` +$ codefresh get image b5f103a87856 --output=yaml | yq -r .annotations.coverage +75 +``` + +You can then easily process the metadata (e.g. with scripts) and take decisions according to them. Here is an example +step that will fail the build if test coverage on an image is less than 80% + + `YAML` +{% highlight yaml %} +version: '1.0' +steps: + findLabel: + title: Get image label for coverage + image: codefresh/cli + commands: + - export MY_COVERAGE=$(codefresh get image b5f103a87856 --output=yaml | yq -r .annotations.coverage) + - echo "Coverage is $MY_COVERAGE" + - if [[ $MY_COVERAGE -lt "80" ]]; then exit 1 ; fi + +{% endhighlight %} + +The possibilities are endless as you can take any combination of image metadata and use any complex conditional +in order to process them in a Codefresh pipeline. + + +### See also + +* [External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +* [Accessing a Docker registry from your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/access-docker-registry-from-kubernetes/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) diff --git a/_docs/ci-cd-guides/first-pipeline.md b/_docs/pipelines/first-pipeline.md similarity index 100% rename from _docs/ci-cd-guides/first-pipeline.md rename to _docs/pipelines/first-pipeline.md diff --git a/_docs/pipelines/hooks.md b/_docs/pipelines/hooks.md new file mode 100644 index 00000000..8996932c --- /dev/null +++ b/_docs/pipelines/hooks.md @@ -0,0 +1,634 @@ +--- +title: "Hooks" +description: "Execute commands before/after each pipeline or step" +group: codefresh-yaml +toc: true +--- + +Pipeline hooks allow you to run specific actions at the end and the beginning of the pipeline as well as before/after a step. + +Hooks can be a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) as you need to define: + +1. A Docker image that will be used to run specific commands. +1. One or more commands to run within the context of that Docker image. + +For simple commands we suggest you use a small image such as `alpine`, but any Docker image can be used in hooks. + +## Pipeline hooks + +Codefresh allows you to run a specific step before each pipeline as well as after it has finished. + +### Running a step at the end of the pipeline + +You can easily run a step at the end of pipeline, that will execute even if one of the steps have failed (and thus the pipeline is stopped in middle): + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_finish: + exec: + image: alpine:3.9 + commands: + - echo "cleanup after end of pipeline" + +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Hello world" + step2: + title: "Step 2" + type: "freestyle" + image: node:10-buster + commands: + - echo "There was an error" + - exit 1 +{% endraw %} +{% endhighlight %} + +In the example above we define a hook for the whole pipeline that will run a step (the `exec` keyword) inside `alpine:3.9` and will simply execute an `echo` command. Because we have used the `on_finish` keyword, this step will execute even if the whole pipeline fails. + +This scenario is very common if you have a cleanup step or a notification step that you always want to run at the end of the pipeline. You will see the cleanup logs in the top pipeline step. + + {% include +image.html +lightbox="true" +file="/images/codefresh-yaml/hooks/cleanup-step.png" +url="/images/codefresh-yaml/hooks/cleanup-step.png" +alt="Running a cleanup step" +caption="Running a cleanup step" +max-width="80%" +%} + +Apart from the `on_finish` keyword you can also use `on_success` and `on_fail` if you want the step to only execute according to a specific result of the pipeline. It is also possible to use multiple hooks at the same time: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_finish: + exec: + image: alpine:3.9 + commands: + - echo "cleanup after end of pipeline" + on_success: + exec: + image: alpine:3.9 + commands: + - echo "Send a notification only if pipeline was successful" + on_fail: + exec: + image: alpine:3.9 + commands: + - echo "Send a notification only if pipeline has failed" +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Hello world" + step2: + title: "Step 2" + type: "freestyle" + image: node:10-buster + commands: + - echo "There was an error" + - exit 1 #Comment this line out to see how hooks change + +{% endraw %} +{% endhighlight %} + +Note that if you have multiple hooks like the example above, the `on_finish` segment will always execute after any `on_success`/`on_fail` segments (if they are applicable). + + +### Running a step at the start of the pipeline + +Similar to the end of the pipeline, you can also execute a step in the beginning of the pipeline with the `on_elected` keyword: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: + exec: + image: alpine:3.9 + commands: + - echo "Creating an adhoc test environment" + on_finish: + exec: + image: alpine:3.9 + commands: + - echo "Destroying test environment" +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests on test environment" + step2: + title: "Step 2" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running acceptance tests on test environment" + +{% endraw %} +{% endhighlight %} + +All pipeline hooks will be shown in the "initializing process" logs: + + {% include +image.html +lightbox="true" +file="/images/codefresh-yaml/hooks/before-pipeline.png" +url="/images/codefresh-yaml/hooks/before-pipeline.png" +alt="Hooks before a pipeline" +caption="Hooks before a pipeline" +max-width="80%" +%} + +It is possible to define all possible hooks (`on_elected`, `on_finish`, `on_success`, `on_fail`) in a single pipeline, if this is required by your development process. + +## Step hooks + +Hooks can also be defined for individual steps inside a pipeline. This capability allows for more granular control on defining prepare/cleanup phases for specific steps. + +The syntax for step hooks is the same as pipeline hooks (`on_elected`, `on_finish`, `on_success`, `on_fail`), you just need to put the respective segment under a step instead of the root of the pipeline. + +For example, this pipeline will always run a cleanup step after integration tests (even if the tests themselves fail). + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + step1: + title: "Compile application" + type: "freestyle" + image: node:10-buster + commands: + - echo "Building application" + step2: + title: "Unit testing" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running unit tests" + hooks: + on_finish: + exec: + image: alpine:3.9 + commands: + - echo "Create test report" + step3: + title: "Uploading artifact" + type: "freestyle" + image: node:10-buster + commands: + - echo "Upload to artifactory" +{% endraw %} +{% endhighlight %} + + +Logs for steps hooks are shown in the log window of the step itself. + + {% include +image.html +lightbox="true" +file="/images/codefresh-yaml/hooks/step-after.png" +url="/images/codefresh-yaml/hooks/step-after.png" +alt="Hooks before a pipeline" +caption="Hooks before a pipeline" +max-width="80%" +%} + +As with pipeline hooks, it is possible to define multiple hook conditions for each step. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + step1: + title: "Compile application" + type: "freestyle" + image: node:10-buster + commands: + - echo "Building application" + step2: + title: "Security scanning" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Security scan" + hooks: + on_elected: + exec: + image: alpine:3.9 + commands: + - echo "Authenticating to security scanning service" + on_finish: + exec: + image: alpine:3.9 + commands: + - echo "Uploading security scan report" + on_fail: + exec: + image: alpine:3.9 + commands: + - echo "Sending slack notification" + +{% endraw %} +{% endhighlight %} + +The order of events in the example above is the following. + +1. The `on_elected` segment executes first (authentication) +1. The step itself executes (the security scan) +1. The `on_fail` segment executes (only if the step throws an error code) +1. The `on_finish` segment always executes at the end + + +## Running [steps/plugins](https://steps.codefresh.io) in hooks: + +Hooks can use [steps/plugins](https://steps.codefresh.io). With plugin you have to specify: + +- The type field for the step/plugin. +- The arguments needed for the step/plugin. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +hooks: #run slack-notifier hook on build completion + on_finish: + steps: + exec: + type: slack-notifier + arguments: + SLACK_HOOK_URL: '${{SLACK_WEBHOOK_URL}}' + SLACK_TEXT: '${{SLACK_TEXT}}' + +steps: + step1: + title: "Freestyle step" + type: "freestyle" + image: alpine + commands: + - echo "Codefresh" + hooks: #run slack-notifier hook on step completion + on_finish: + steps: + exec: + type: slack-notifier + arguments: + SLACK_HOOK_URL: '${{SLACK_WEBHOOK_URL}}' + SLACK_TEXT: '${{SLACK_TEXT}}' +{% endraw %} +{% endhighlight %} + +## Controlling errors inside pipeline/step hooks + +By default if a step fails within a pipeline, the whole pipeline will stop and be marked as failed. This is also true for `on_elected` segments as well. If they fail, then the whole pipeline will fail (regardless of the position of the segment in a pipeline or step). However, this only applies to `on_elected` segments - `on_success`, `on_fail` and `on_finish` segments do not affect the pipeline outcome at all, and a pipeline will continue even if one of these segments fails. + +For example the following pipeline will fail right away, because the pipeline hook fails at the beginning. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: + exec: + image: alpine:3.9 + commands: + - echo "failing on purpose" + - exit 1 +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests on test environment" +{% endraw %} +{% endhighlight %} + +You can change this behavior by using the existing [fail_fast property]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#execution-flow) inside an `on_elected` hook. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: + exec: + image: alpine:3.9 + fail_fast: false + commands: + - echo "failing on purpose" + - exit 1 +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests on test environment" +{% endraw %} +{% endhighlight %} + +This pipeline will now execute successfully and `step1` will still run as normal, because we have used the `fail_fast` property. You can also use the `fail_fast` property on step hooks as well: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests on test environment" + hooks: + on_elected: + exec: + image: alpine:3.9 + fail_fast: false + commands: + - echo "failing on purpose" + - exit 1 +{% endraw %} +{% endhighlight %} + + +>Notice that the `fail_fast` property is only available for `on_elected` hooks. The other types of hooks (`on_finish`, `on_success`, `on_fail`) do not affect the outcome of the pipeline in any way. Even if they fail, the pipeline will continue running to completion. This behavior is not configurable. + + +## Using multiple steps for hooks + +In all the previous examples, each hook was a single step running on a single Docker image. You can also define multiple steps for each hook. This is possible by inserting an extra `steps` keyword inside the hook and listing multiple Docker images under it: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_finish: + steps: + mycleanup: + image: alpine:3.9 + commands: + - echo "echo cleanup step" + mynotification: + image: cloudposse/slack-notifier + commands: + - echo "Notify slack" +steps: + step1: + title: "Step 1" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests on test environment" +{% endraw %} +{% endhighlight %} + +By default all steps in a single hook segment are executed one after the other. But you can also run them in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#inserting-parallel-steps-in-a-sequential-pipeline): + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + step1: + title: "Compile application" + type: "freestyle" + image: node:10-buster + commands: + - echo "Building application" + step2: + title: "Unit testing" + type: "freestyle" + image: node:10-buster + commands: + - echo "Running Integration tests" + - exit 1 + hooks: + on_fail: + mode: parallel + steps: + upload-my-artifact: + image: maven:3.5.2-jdk-8-alpine + commands: + - echo "uploading artifact" + my-report: + image: alpine:3.9 + commands: + - echo "creating test report" +{% endraw %} +{% endhighlight %} + +You can use multiple steps in a hook in both the pipeline and the step level. + + +## Using annotations and labels in hooks + +The hook syntax can also be used as a unified interface for encompassing the existing syntax of [build annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) and [metadata]({{site.baseurl}}/docs/codefresh-yaml/docker-image-metadata/). + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: + exec: + image: alpine:3.9 + commands: + - echo "Creating an adhoc test environment" + annotations: + set: + - entity_type: build + annotations: + - my_annotation_example1: 10.45 + - my_string_annotation: Hello World +steps: + clone: + title: Cloning source code + type: git-clone + arguments: + repo: 'codefresh-contrib/golang-sample-app' + revision: master + build-image: + type: build + image_name: my-golang-image + working_directory: '${{clone}}' + tag: master + hooks: + on_success: + exec: + image: alpine:3.9 + commands: + - echo "Scanning docker image" + metadata: # setting metadata + set: + - '${{build-image.imageId}}': + - status: 'Success' +{% endraw %} +{% endhighlight %} + +Note however, that if you decide to use annotations and metadata inside hooks, you cannot mix and max the old syntax with the new syntax. + +The following pipeline is **NOT** valid: + +`invalid-codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + test: + image: alpine + on_success: # you cannot use old style together with hooks + annotations: + set: + - entity_type: build + annotations: + - status: 'success' + commands: + - echo block + hooks: + on_success: + annotations: + set: + - entity_type: build + annotations: + - status: 'success' +{% endraw %} +{% endhighlight %} + +The pipeline is not correct, because the first segment of annotations is directly under `on_success` (the old syntax), while the second segment is under `hooks/on_success` (the new syntax). + + +## Syntactic sugar syntax + +To simplify the syntax for hooks, the following simplifications are also offered: + +If you do not want to use metadata or annotations in your hook the keyword `exec` can be omitted: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_finish: # no exec keyword + image: notifications:master + commands: + - ./send_workflow_finished.js +steps: + build: + type: build + image_name: my_image + tag: master + hooks: + on_fail: # no exec keyword + image: notifications:master + commands: + - ./send_build_failed.js +{% endraw %} +{% endhighlight %} + + +If you do not want to specify the Docker image you can simply omit it. Codefresh will use the `alpine` image in that case to run the hook: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: + exec: # no image keyword - alpine image will be used + - echo "Pipeline starting" +steps: + build: + type: build + image_name: my_image + tag: master + hooks: + on_success: # no image keyword - alpine image will be used + exec: + - echo "Docker image was built successfully" + annotations: + set: + - entity_type: build + annotations: + - status: 'Success' +{% endraw %} +{% endhighlight %} + + + If you don't use metadata or annotations, you can also completely remove the `exec` keyword and just mention the commands you want to run (`alpine` image will be used by default): + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +hooks: + on_elected: # no exec/image keyword - alpine image will be used + - echo "Pipeline starting" +steps: + build: + type: build + image_name: my_image + tag: master + hooks: + on_success: # no exec/image keyword - alpine image will be used + - echo "Docker image was built successfully" +{% endraw %} +{% endhighlight %} + +## Using Type Steps / Plugins in hooks + +You can use a type step / plugins in hooks. With this you will need to change `exec` into `steps` with the information needed for the step. + +Below is an example pipeline hook using the `slack-notifier` step/plugin for when the pipeline starts. + +```yaml +hooks: + on_elected: + steps: + exec: + slack_pending: + type: slack-notifier + arguments: + SLACK_HOOK_URL: {% raw %}'${{SLACK_WEBHOOK_URL}}'{% endraw %} + SLACK_TEXT: '*Build Started* :crossed_fingers:' +``` + +## Limitations of pipeline/step hooks + +With the current implementation of hooks, the following limitations are present: + +* The [debugger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/debugging-pipelines/) cannot inspect commands inside hook segments +* Hooks are not supported for [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +* Storage integrations don't resolve in hooks (for example, [test reports]({{site.baseurl}}/docs/testing/test-reports/#producing-allure-test-reports-from-codefresh-pipelines)) +* Step hook does not support the working_directory field aka `working_directory: ${{clone}}` + +## What to read next + +* [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +* [Condition Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +* [Working Directories]({{site.baseurl}}/docs/codefresh-yaml/working-directories/) +* [Annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) + + diff --git a/_docs/pipelines/introduction-to-codefresh-pipelines.md b/_docs/pipelines/introduction-to-codefresh-pipelines.md new file mode 100644 index 00000000..fd87b5f1 --- /dev/null +++ b/_docs/pipelines/introduction-to-codefresh-pipelines.md @@ -0,0 +1,341 @@ +--- +title: "Introduction to Codefresh pipelines" +description: "Understand how Codefresh pipelines work" +group: configure-ci-cd-pipeline +redirect_from: + - /docs/introduction-to-codefresh-pipelines/ + - /docs/configure-ci-cd-pipeline/ +toc: true +--- + + +The central component of the Codefresh Platform are pipelines. Pipelines are workflows that contain individual steps. +Each step is responsible for a specific action in the process. Pipelines can be used to: + +* Compile and package code +* Build Docker images +* Push Docker images to any [Docker Registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +* Deploy applications/artifacts to VMs, Kubernetes clusters, FTP sites, S3 buckets etc. +* Run [unit tests]({{site.baseurl}}/docs/testing/unit-tests/), [integration tests]({{site.baseurl}}/docs/testing/integration-tests/), acceptance tests etc. +* Any custom action that you define + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/complex-pipeline.png" +url="/images/codefresh-yaml/stages/complex-pipeline.png" +alt="Codefresh pipelines" +caption="Codefresh pipelines" +max-width="90%" +%} + +## Why Codefresh is different + +Codefresh offers unique characteristics in pipelines that serve as the cornerstone of the build/deploy process: + +1. All [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) in Codefresh pipelines are executed inside a Docker container of your choosing. +1. All steps in Codefresh share the same "workspace" in the form of a shared Docker volume. +1. The shared Docker volume is automatically cached between pipeline executions. +1. Each successful pipeline automatically pushes its Docker image to the default Docker registry defined in your account. +1. Codefresh has a distributed Docker cache for all build nodes and caches layers similar to the docker daemon on your workstation. This is fully automated, and no configuration is needed in order to activate it. + +### Using Docker containers as build tooling + +Unlike traditional solutions, Codefresh was built from the ground up to have full Docker support. All Codefresh pipelines +deal with Docker images, either using them as runtime tools or creating them as deployment artifacts. +Everything that happens in Codefresh uses a Docker image behind the scenes. + +It is important that you understand how to take advantage of Docker-based pipelines as they are much more powerful than +traditional VM solutions. The capability to define your own tooling cannot be understated. It is the fastest way to take +full control of your build tools and to upgrade them easily. + +With traditional VM-based build solutions you are constrained on the build and deployment tools provided by the vendor. +If for example you need a new version of Node/Java/Python other than the one that is provided on the build slave, you have to wait for your vendor to add it. If you need to use a special tool (e.g terraform, gcloud) and the vendor does +not support it you are out of luck. + +With Codefresh you don't care about what is installed in the runners that execute your builds. They can run *any* Docker image of your choosing. You are free to update the version of the image used at any given time. + +Here is an example: + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/steps-example1.png" +url="/images/pipeline/introduction/steps-example1.png" +alt="Codefresh steps example 1" +caption="Pipeline with 3 steps" +max-width="70%" +%} + + +1. The first step runs under the context of a Node image that prepares the application and runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/). +1. The second step uses an image with s3 command line tools and uploads the test results to a bucket that holds test reports. +1. The helm step creates a Helm chart and pushes it to a Helm repository. + +You don't need to contact Codefresh and ask them to add the s3 executable on the build runners. You just use a premade Docker image that contains it. The version used for Node is defined by you and if you wish to upgrade to another version +you simply change the definition of the pipeline. + + +Here is another example: + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/steps-example2.png" +url="/images/pipeline/introduction/steps-example2.png" +alt="Codefresh steps example 2" +caption="Pipeline with 4 steps" +max-width="70%" +%} + +1. The first step runs under the context of a Maven image that compiles the code and creates an executable. +1. The second step uses a Docker image that contains terraform and creates a single ECS instance in AWS. +1. The third step uses a custom Docker image that deploys to the ECS container that was just created. +1. The last step uploads the Maven reports that were created in step 1 to an FTP site. + +You should now start seeing the endless possibilities. You can mix and match any Docker image (either a public one +or your own) to use a build context in your step. This makes Codefresh a future-proof solution for all build tools +that exist now and all of them that will appear in the future. As long as there is a Docker image for a tool, Codefresh +can use it in a pipeline without any extra configuration. + +Codefresh also offers a [plugin marketplace](https://codefresh.io/steps/) with several existing plugins. + +{% include +image.html +lightbox="true" +file="/images/pipeline/plugin-directory.png" +url="/images/pipeline/plugin-directory.png" +alt="Codefresh steps directory" +caption="Codefresh steps directory" +max-width="80%" +%} + + +All plugins in the marketplace are open-source and we accept external contributions so you can easily add your own. + + +### Sharing the workspace between build steps + +We have seen in the previous section that Codefresh can use Docker images as the context of a build step. The second +important point to understand regarding Codefresh pipelines is that the default workspace of each step is shared between all steps in a pipeline. + +This happens via a Docker volume which is attached to all Docker containers that represent each step. This volume is +always available at `/codefresh/volume` and is used as the parent folder where the project is cloned. + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/codefresh-volume.png" +url="/images/pipeline/introduction/codefresh-volume.png" +alt="Codefresh volume" +caption="All steps share the same volume" +max-width="90%" +%} + +Anything that is placed on this volume will be available to all steps of the pipeline (as well as to subsequent executions of the same pipeline as we will see later). + +Again, this places Codefresh ahead of traditional solutions that execute build steps in a completely isolated manner. +In traditional VM-based builds, using artifacts produced from one step to another, is a complicated process as one +must declare which artifact folders should be re-used. Artifact re-use sometimes happens with compression/decompression +of the respective folder resulting in really slow builds if a project is very big. + +Codefresh does not need to bother the user with artifact reuse across steps. *Anything* that is placed in the shared Codefresh volume will automatically be available to the next steps in the pipeline without any extra configuration. + +Example 1 + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/codefresh-volume-example1.png" +url="/images/pipeline/introduction/codefresh-volume-example1.png" +alt="Codefresh volume example 1" +caption="Re-using Node Modules" +max-width="90%" +%} + +1. The first step runs `npm install` and downloads all libraries in `node_modules` into the shared Codefresh volume. +1. The second step runs `npm test`. The folder `node_modules` is still present from the previous step. + +Example 2 + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/codefresh-volume-example2.png" +url="/images/pipeline/introduction/codefresh-volume-example2.png" +alt="Codefresh volume example 2" +caption="Re-using Test reports" +max-width="90%" +%} + +1. The first step runs `mvn test` and produces some test reports in `target/surefire-reports` into the shared Codefresh volume. +1. The next step uploads these reports using FTP to an external site. + + +The common volume shared among build steps makes it very easy to create pipelines that work in a gradual manner +where any step in the pipeline is using artifacts produced by a previous one. + +>The shared volume is **NOT available** in [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080). There is no folder `/codefresh/volume` inside a Dockerfile for you to access. + +You can also use [environment variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) to share information between steps. All predefined environment variables +are available to all steps, and each individual step can use `cf_export` to inject dynamically during the build process +extra environment variables. + + +## Working with Codefresh pipelines + +Now that we know the basics, we can see how you can take advantage of Docker-based pipelines in order +to build and deploy your projects. + + +### Cloning the source code + +You can clone source code using the built-in [git-clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) as the first step in a Pipeline or run manually your own git clone commands in a freestyle step. Codefresh has built-in [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) with all popular git providers (both cloud and on-premises installations). + +Codefresh uses the shared volume as the parent folder of the project. So if your pipeline is connected to a GIT repo that contains `my-project` the following will happen: + +* `/codefresh/volume` is the shared directory for all steps +* `/codefresh/volume/my-project` is where the source code exists. This is also the current working directory +* Any other directory (e.g. `/bin`, `/var`, `/opt`) depends on the current container image that is used as build context + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/checkout.png" +url="/images/pipeline/introduction/checkout.png" +alt="Codefresh checkout folder" +caption="Codefresh checkout folder" +max-width="80%" +%} + +There are three important points to consider regarding these folders. + +First, the [working directory]({{ site.baseurl }}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#working-directories) of each step is by default the project folder (e.g. `/codefresh/volume/my-project`). Therefore +your build step can run commands exactly as you would run them locally (e.g. `npm install, pip install, mvn package, bundle install`). + +Secondly, notice that the project folder is placed on the Codefresh volume, so by default it is also available to all other steps. The code that you checkout in the beginning, as well as all other files that are created on it, will +be available to all steps. Once you create `node_modules`, or any other folder that exists inside the project folder, it will automatically persist for all other steps. + +Finally, `/codefresh/volume` is an internal folder name and you should use `{% raw %}${{CF_VOLUME_PATH}}{% endraw %}` in your codefresh.yml file +if you really want to reference this folder. You can also reference your project folder as `{% raw %}${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}{% endraw %}` if you need it. + +See the [System Provided Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/#system-provided-variables) section for more information. + +### Working with Docker inside a Codefresh pipeline + +We have already seen that Codefresh pipelines are based on Docker images and that each step runs inside the context of a Docker container. You might be wondering how you can run Docker commands directly inside a Codefresh pipeline. + +The answer is that you don't. Even though in the future Codefresh might allow for Docker-in-Docker capabilities, at the moment this is not supported for security reason (only enterprise customers have access to the underlying Docker daemon). Any scripts that you already have that run Docker commands on their own will need to be adapted to Codefresh pipelines. + +Usually you want to run a docker command for four reasons: + +1. To build a Docker image +1. To push a Docker image +1. To run a docker-compose setup +1. To run a Docker container + +For all these situations Codefresh gives you special pipeline steps that perform the respective action. These are: + +1. The [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +1. The [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) +1. The [compositions step]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) +1. The [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + +The commands you define in a freestyle step run automatically in a Docker container that is attached to that step once the pipeline executes. + +Therefore, this command on your local workstation: + +``` +docker run python:3.6.4-alpine3.6 pip install . +``` + +will become in Codefresh + +``` +CollectAllMyDeps: + title: Install dependencies + image: python:3.6.4-alpine3.6 + commands: + - pip install . +``` +For the plugins in the [Step Marketplace](https://codefresh.io/steps/) we already give an example of the YAML part that must be included in your pipeline: + +{% include +image.html +lightbox="true" +file="/images/pipeline/plugin-example.png" +url="/images/pipeline/plugin-example.png" +alt="Codefresh steps directory" +caption="Codefresh steps directory" +max-width="50%" +%} + +Each plugin also defines its input/output in the form of environment variables and files. + +### Creating Docker images dynamically as build tools + + +Now we reach one of the most powerful features of Codefresh pipelines. We have already seen that [freestyle pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) are just a series of commands that run inside the context of a Docker container. In most cases the images used +for the freestyle steps are known in advance and come from public (e.g. Dockerhub) or [private Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). + +Codefresh is one the few CI/CD solutions that not only offers easy Docker registry integration + accessible to all pipelines +but also allows you to **build docker images on demand in the same pipeline where they are required**. + +This means that you can create a special Docker image in an early step inside a Codefresh pipeline and then reference it in a later step in the same pipeline. + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/dynamic-docker-builds.png" +url="/images/pipeline/introduction/dynamic-docker-builds.png" +alt="Codefresh dynamic docker builds" +caption="Creating dynamically Docker images as build steps" +max-width="90%" +%} + +Let's say for example that you are moving a legacy application to Codefresh which is deployed using a special Python script. Your main application is a Ruby-On-Rails app. Both applications exist in the same git repository (we mention this for simplicity reasons, Codefresh also supports checking out code from multiple repositories). + +You can create a single pipeline with Codefresh that does the following: + +1. Checks out the code +1. Creates a Docker image based on Python for the deployment tool +1. Uploads the Python tool Docker image to the internal registry +1. Builds the Ruby application using a freestyle step with the R-O-R image from Dockerhub +1. Deploys the Ruby application by running the Python based deployment tool image (after pulling it first) + +This concept is ground-breaking as it allows you to automatically update your build tools that are used in any pipeline. +Even though you could manually create the Docker images yourself before-hand, it is better to completely automate them +inside the pipeline they are actually needed. This ensures that both the application and its tooling are always at the latest version. + +### How caching works in Codefresh + +Codefresh employs several caching mechanisms for both Dockerized and non-dockerized applications. The shared volume is also cached behind the scenes automatically. See our [caching guide]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) for more details. + +### Calling other pipelines + +It is also possible to chain multiple Pipelines together in Codefresh. To accomplish this, Codefresh offers +a special Docker image that contains the [Codefresh CLI](https://codefresh-io.github.io/cli/) and allows you to trigger another pipeline using its name. + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/call-pipeline.png" +url="/images/pipeline/introduction/call-pipeline.png" +alt="Codefresh call pipeline" +caption="Calling another pipeline" +max-width="80%" +%} + +Notice that each Pipeline in Codefresh is completely isolated from the other. They use a different Docker volume so the build context of each one cannot access files from the other. This may change in the future, but for the time being +you should know that only steps within the same pipeline can share artifacts. + +## What to read next + +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Build and Docker caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) + + + diff --git a/_docs/pipelines/monitoring-pipelines.md b/_docs/pipelines/monitoring-pipelines.md new file mode 100644 index 00000000..9aae7333 --- /dev/null +++ b/_docs/pipelines/monitoring-pipelines.md @@ -0,0 +1,464 @@ +--- +title: "Monitoring pipelines" +description: "Viewing your builds and logs" +group: configure-ci-cd-pipeline +toc: true +--- + + +All pipeline activity in Codefresh can be viewed on the *Builds* tab. +There is one global view from the left-side menu that shows builds for all projects +across your organization and a project-based view from the settings inside an individual project. + +Both views have the same controls and filters. + +## Viewing pipeline status + +Each screen contains all builds sorted from the most recent to the oldest. The first time you visit +the screen there are no filters defined. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/builds-dashboard.png" +url="/images/pipeline/monitoring/builds-dashboard.png" +alt="Pipeline Activity in Codefresh" +caption="Pipeline activity" +max-width="80%" +%} + +By default, it shows all builds that is happening in Codefresh. To narrow the list you can use the filters on the top +of the screen. + +### Applying filters on the build view + +Directly above the list you can find several filters. + +At the most basic level you can choose between + + * *Running* builds that are currently executing + * *Pending* builds which are queued and waiting to start + * *Delayed* builds which cannot run yet, because there are no free pipeline builders. + A build can be delayed for a maximum of seven days, and each account can have up to 1000 delayed builds at any time. + * Builds that are delayed for more than seven days are terminated with a _Delay time limit exceeded_ reason. + * If the total number of delayed builds exceed 1000, older builds are terminated with a _Maximum delayed workflows exceeded_ reason. + + * *All* builds regardless of running stage (this is the default) + +You can further filter the builds by choosing the various filter types that specify the build job. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-filtering.png" +url="/images/pipeline/monitoring/build-filtering.png" +alt="Pipeline filters in Codefresh" +caption="Available filters" +max-width="50%" +%} + +The available filters are: + +* *Pipeline* - any of the pipelines available. +* *Provider* - type of [Git provider]({{site.baseurl}}/docs/integrations/git-providers/). +* *Repository* - Git repository from the attached [trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/). +* *Type* - build, [launch a test environment]({{site.baseurl}}/docs/getting-started/on-demand-environments/#launching-a-docker-image-using-codefresh). +* *Branch* - any of the available branches from the attached Git trigger. +* *Committer* - person that made the commit that triggered the build. +* *Environment* - which [environment]({{site.baseurl}}/docs/deploy-to-kubernetes/environment-dashboard/) was affected. +* *Status* - success, error, in-progress, pending, terminated etc. A Pending status can also indicate that [pipeline build execution has been paused]({{site.baseurl}}/docs/administration/pipeline-settings/#pause-pipeline-executions) for the account. +* *Trigger type* - what type of trigger was responsible for this build +* *Git event* - in the case of [git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) the exact event + +Notice that all filters are multiple-choice so you can select multiple values for each filter category. +At any given point you can see all the active filters on top of the screen. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/possible-filters.png" +url="/images/pipeline/monitoring/possible-filters.png" +alt="Pipeline filters in Codefresh" +caption="Active filters" +max-width="50%" +%} + +You can easily remove active filters, by clicking on them and adding/removing values. + +On the right hand side you can also find a filtering toolbar with time options: + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-filter-date.png" +url="/images/pipeline/monitoring/build-filter-date.png" +alt="Filtering options for time" +caption="Filtering options for time" +max-width="60%" +%} + +You can combine all previously mentioned filters with the time based filters. + +### Creating build views + +Once you have a set of filters that you use regularly, you can save them as a custom *Build View* by clicking the *Save as View* button +and providing a name. + +Now you can select at the top of the window any of the available build views to automatically filter results according to the respective sets of filters. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-view-selection.png" +url="/images/pipeline/monitoring/build-view-selection.png" +alt="Build View selection" +caption="Build View selection (click to enlarge)" +max-width="50%" +%} + +You can delete existing build-views by clicking on the *manage views* button. +You can change the filters of an existing build view by making a new filter selection and then saving the view with an existing name (effectively overwriting it). + + +### Build details + + +For each individual build you can see several details such as the git hash, the person who made the commit, the pipeline that was triggered as well as how much time it took. For each event type you will also see additional context related information. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-details-entry.png" +url="/images/pipeline/monitoring/build-details-entry.png" +alt="build details in Codefresh" +caption="Build details" +max-width="100%" +%} + +Child builds triggered by other builds are identified in the Event column by the icon {::nomarkdown} {:/}. +The Parent Build column shows the link to the parent build. Mouse over to see the tooltip with information on the parent build. The tooltip includes links to the parent build, repo, branch, commit message, and the ability to filter by repo and branch. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/child-parent-build-info.png" +url="/images/pipeline/monitoring/child-parent-build-info.png" +alt="Child build in Builds list" +caption="Child build in Builds list" +max-width="70%" +%} + +There are also extra options if you click the small "3-dot" menu button on the right. For a particular build, you can: + +- View the logs +- View the YAML +- View or add [annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +- View the images produced (and consequently launch an on-demand [test environment]({{site.baseurl}}/docs/getting-started/on-demand-environments/#launching-a-docker-image-using-codefresh)) + +Notice that if you restart a pipeline it will trigger with the exact settings it *originally* had. So +if this was a manual trigger where you [disabled caching]({{site.baseurl}}/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) or changed the [notification options](#monitoring-pipelines-that-check-pull-requests), the new +execution will still honor those settings (even if you have changed them for later builds). + +An extra button for test reports will be visible if you are using the [test report feature]({{site.baseurl}}/docs/testing/test-reports/) of Codefresh. + + +## Viewing details for an individual pipeline build + +If you click on any individual pipeline build, you will enter the pipeline build information screen. +From here you can see more details for a build such as the logs, running time and resource metrics. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/pipeline-view.png" +url="/images/pipeline/monitoring/pipeline-view.png" +alt="Pipeline view" +caption="Pipeline view" +max-width="80%" +%} + +Each section in this screen corresponds to each pipeline step. There are two special steps: + +* *Initializing Process* +* *Cloning Main Repository* + +These are Codefresh built-in steps and will appear for most builds (you can also create a pipeline that doesn't clone a git repository by default). The rest of the step names depend on your `codefresh.yml` (or the default step names provided by Codefresh). The different columns take the names from the defined [pipeline stages]({{site.baseurl}}/docs/codefresh-yaml/stages/). + +### Viewing status for pipeline steps + +Monitor the status of the steps in the pipeline as they are executed. + +{: .table .table-bordered .table-hover} +| Step Status Icon | Description | +| ------------------------| ---------------- | +|{::nomarkdown} {:/}| Pipeline step completed successfully. | +|{::nomarkdown} {:/}| Pipeline step pending approval has been approved, either manually or automatically. | +|{::nomarkdown} {:/}| Pipeline step pending approval has been denied approval. | +|{::nomarkdown} {:/}| Pipeline step currently running. | +|{::nomarkdown} {:/}| Pipeline step running in debug mode. See [Debugging pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/debugging-pipelines/) for more information. | +|{::nomarkdown} {:/}| Pipeline step gracefully terminating execution. | +|{::nomarkdown} {:/}| Pipeline step execution has been manually or automatically terminated. | +|{::nomarkdown} {:/}| Pipeline step execution has been terminated because of error. | + + + +### Viewing/downloading logs for builds and build steps + +View logs for running and completed builds and download them in HTML or text formats. +You can view logs online, for the entire build or for single or specific steps in the build. Similarly, you can download the logs for the entire build, or for single or specific steps. +The Filter Logs option is useful to view and manage logs, especially for large builds as there is a max size limit for logs. You can also search logs. + +>Note: + The max log size for the entire build is 100MB, and 20MB per step. The system stops generating logs once the build size is exceeded. + For large builds, it is easier to filter the logs by single or multiple steps, and then view/download them. + +1. In the **Builds** page, select a build. +1. To view logs online for the selected build, click **Output** in the lower part of the Build page. +1. Optional. Select **Filter Logs** and then select the step or steps for which view/download logs. + Logs are displayed for the selected steps. +1. From either the context menu on the top-right of the toolbar or from the Output pane, select **Download as HTML** or **Download as text**. + The log file is downloaded with the build ID as the filename, including also the step name if the log is for a single step, in the format `'. + + {% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-logs.png" +url="/images/pipeline/monitoring/build-logs.png" +alt="Build log in Codefresh" +caption="Build log in Codefresh" +max-width="60%" +%} + + +### Viewing variables in pipeline builds + +Variables, both system (environment) and custom (user-defined), are injected into pipelines from different sources and at different levels. +The variables actually used by a specific build of the pipeline varies according to the events that triggered the pipeline. +Select a build to view all its variables, and identify their source, and overrides if any. + +1. In the **Builds** page, either select the build and then open the context-menu, or open the context-menu on the right of the build entry. +1. Select **Variables**. + + {% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-variables-view-option.png" +url="/images/pipeline/monitoring/build-variables-view-option.png" +alt="Variables option in context menu of build entry" +caption="Variables option in context menu of build entry" +max-width="70%" +%} + +{:start="3"} +1. If required, click the Sort icon for the group to sort in alphabetical order. +1. To copy the group's variables to the clipboard, click the Copy icon. + + +Here's an example of the list of variables for a pipeline build. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-variables-list.png" +url="/images/pipeline/monitoring/build-variables-list.png" +alt="List of variables in selected build" +caption="List of variables in selected build" +max-width="50%" +%} + +The variables are grouped by granularity, starting with the global project-level variables and ending with the trigger-level variables with the highest granularity: +* Project +* Shared configuration +* Pipeline +* Trigger + +A variable with a strikethrough indicates an override by the same variable in a lower-level group. For rules on precedence and overrides for variables in builds, see [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/). + +>Notes: + * Variables exported across steps with `cf_export` are not identified as `cf-exported` variables in the list. + * Secret-type variables are always masked. + + + +### Reviewing the yaml for the pipeline + +From the step details you can also click on the yaml tab to see the yaml segment for that individual step: + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/yaml-from-step.png" +url="/images/pipeline/monitoring/yaml-from-step.png" +alt="Step Yaml" +caption="Step Yaml" +max-width="60%" +%} + +If you want to see the yaml for the whole pipeline, +- Click the *YAML* tab on the bottom left corner without selecting a step first or +- Select the three dots next to the "RESTART" button on the top-right, and click on *Show YAML* + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/view-pipeline-yaml.png" +url="/images/pipeline/monitoring/view-pipeline-yaml.png" +alt="Pipeline Yaml" +caption="Pipeline Yaml" +max-width="60%" +%} + +In both cases you can copy to clipboard the yaml shown using the button at the top left corner. + +### Viewing pipeline metrics + +Codefresh offers several metrics for pipeline steps that allow you to get a better overview on the resources +consumed by your pipeline. + +At the most basic level Codefresh will show some quick metrics while the pipeline is running that include +memory consumed and size of logs: + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/quick-pipeline-metrics.png" +url="/images/pipeline/monitoring/quick-pipeline-metrics.png" +alt="Pipeline running metrics" +caption="Pipeline running metrics" +max-width="70%" +%} + +You can then get the memory usage for the whole pipeline by clicking on the metrics tab at the bottom of the screen. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/pipeline-metrics.png" +url="/images/pipeline/monitoring/pipeline-metrics.png" +alt="Pipeline detailed metrics" +caption="Pipeline detailed metrics" +max-width="70%" +%} + + +If you click on an individual step before clicking the *Metrics* tab you will get metrics for that specific step only. + + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/step-metrics.png" +url="/images/pipeline/monitoring/step-metrics.png" +alt="Step metrics" +caption="Step metrics" +max-width="70%" +%} + + +### Restarting the pipeline + +You can choose to restart any pipeline by clicking the button at the top right corner. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/restart-pipeline.png" +url="/images/pipeline/monitoring/restart-pipeline.png" +alt="Restart a pipeline" +caption="Restart a pipeline" +max-width="70%" +%} + +>It is important to note that "Restart from beginning" will restart a pipeline with the **same** state that it had in its original execution (including the original git commit). If you want to execute a pipeline again with a new state instead, you need to use the *Run* button in the [pipeline editor]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#using-the-inline-pipeline-editor) and selecting any of the available [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/). + + + +If the pipeline has failed, you can choose to restart it only from the failed step and onwards. + +You can also restart from a failed step right from the graphical view: + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/restart-failed.png" +url="/images/pipeline/monitoring/restart-failed.png" +alt="Restart from a failed step" +caption="Restart from a failed step" +max-width="70%" +%} + +>Notice again that restarting a pipeline from a failed step means restarting the pipeline with the **same** state that it had at the point in time (including the original git commit). + +If your pipeline has some flaky steps, you can also use the [retry syntax]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step) in your yaml instead of restarting them manually each time they fail. + + +## Monitoring Pipelines outside the Codefresh UI + +You don't always have to be in the Codefresh UI in order to monitor the status of your builds. + + +### Monitoring Pipelines that check Pull requests + +One of the most +important roles of a CI platform is to automatically update the status of a GIT Pull request with the result +of the respective build. + +{% include +image.html +lightbox="true" +file="/images/getting-started/quick-start-test-pr/auto-build-pr.png" +url="/images/getting-started/quick-start-test-pr/auto-build-pr.png" +alt="Pull Request Status" +caption="Pull Request Status (click image to enlarge)" +max-width="50%" +%} + +If you have setup a [GIT trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) in Codefresh then by default this happens automatically without any other configuration +for all automated commits (that are coming from webhooks). + +If you start a build manually then by default the git status will **not** be updated (i.e. the result of the pipeline +will not affect the status of Pull request) + +If you don't want this behavior to happen, you can enable the git status update checkbox when you launch a pipeline. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/report-notification-checkbox.png" +url="/images/pipeline/monitoring/report-notification-checkbox.png" +alt="Update git status for pipelines triggered manually " +caption="Update git status for pipelines triggered manually (click image to enlarge)" +max-width="50%" +%} + +This way the pipeline status *will* change the build status even with manual builds. + +The same behavior is also available to the [Codefresh CLI](https://codefresh-io.github.io/cli/pipelines/run-pipeline/). In that case use the parameter `--enable-notifications` +to specify if manually triggering a build will also change the GIT status. + +For open source projects you also have the ability to [trigger builds from external forks]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/#support-for-building-pull-requests-from-forks). + +### Viewing Pipeline status from text/html files + +Codefresh also supports build badges that allow you to show the +status of a Pipeline in Text files or web pages. + +{% include +image.html +lightbox="true" +file="/images/pipeline/monitoring/build-badge.png" +url="/images/pipeline/monitoring/build-badge.png" +alt="Codefresh build badges" +caption="Codefresh build badges" +max-width="100%" +%} + +See the [build badges page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) for more information. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Test report]({{site.baseurl}}/docs/configure-ci-cd-pipeline/test-reports/) +* [Status badges]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) diff --git a/_docs/pipelines/pipeline-caching.md b/_docs/pipelines/pipeline-caching.md new file mode 100644 index 00000000..acd9ecc8 --- /dev/null +++ b/_docs/pipelines/pipeline-caching.md @@ -0,0 +1,315 @@ +--- +title: "Pipeline caching" +description: "Faster builds with Codefresh caching" +group: configure-ci-cd-pipeline +toc: true + +--- + +One of the unique features of Codefresh is the multitude of caching systems that take part in a pipeline, and in particular the caching mechanisms targeted specifically at Docker builds. Most types of caching are completely automatic and require zero configuration in order to activate. Caching is a built-in feature in all Codefresh accounts regardless of pricing tier (even free accounts have all types of caching enabled). + +## Types of caching + +Here is a quick overview of all types of caching used in a Codefresh pipeline: + +{: .table .table-bordered .table-hover} +| Caching mechanism | Activation | Used in | Comments | +| -------------- | ---------------------------- |-------------------------| -------------------------| +| Distributed Docker step/image caching | Automatic | All pipeline [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) | | +| Distributed Docker layer caching | Automatic | Pipeline [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | Mimics local Docker layer cache| +| Caching from previous built image | Automatic | Pipeline build steps | Distributed version of `--cache-from`| +| Docker registry caching | Automatic | Pipeline build steps | Works for all [connected Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/)| +| Traditional build caching | Automatic/manual | Pipeline [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | See notes for [parallel builds]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/)| + +All these caching mechanisms are enabled by default and you can [freely disable them]({{site.baseurl}}/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) if you encounter any issues with caching. + +Let's see these caches in order and how to use them effectively. + +## Distributed Docker image caching + +This is the simplest mode of caching available. All Codefresh steps [are in fact docker images]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). Once a pipeline runs for the first time, Codefresh will pull all required images from their registries (either public or private) and will cache them for the next build: + + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/image-caching.png" +url="/images/pipeline/caching/image-caching.png" +alt="Caching pipeline steps" +caption="Caching pipeline steps" +max-width="60%" +%} + +The next time the pipeline runs all images will be fetched from cache. This includes built-in steps (e.g the [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/)), custom steps from [the marketplace](https://codefresh.io/steps/) or your own [dynamic pipeline steps]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#creating-docker-images-dynamically-as-build-tools). + +This cache mechanism is completely automatic and is not user configurable. Some ways that you can affect it are: + +* If you use well known images in your pipeline (such as `alpine`, `node`, `maven` etc) they have more probabilities to be already cached by the Codefresh platform +* Use specific tags for your images (e.g. `alpine:3.9.2` and `maven:3-jdk-11-openj9`) instead of generic ones (e.g `alpine:latest` and `node:buster`) that change all the time +* Using small images in the pipeline will make caching/restoring of pipeline steps much faster. + + +You can see in the [pipeline build logs]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) if the images of your steps are found in cache or not. Here is an example of a cache hit: + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/image-cache-hit.png" +url="/images/pipeline/caching/image-cache-hit.png" +alt="Docker image cache hit" +caption="Docker image cache hit" +max-width="50%" +%} + +and a cache miss: + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/image-cache-miss.png" +url="/images/pipeline/caching/image-cache-miss.png" +alt="Docker image cache miss" +caption="Docker image cache miss" +max-width="50%" +%} + +This cache mechanism is applicable to all Codefresh pipelines and steps. + + +## Distributed Docker layer caching + +This type of caching is **only** applicable to [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) and mimics the ways docker layer caching behaves locally on your workstation. + +When you build images locally, Docker will cache intermediate layers making future builds much faster. You can see when caches are used in your build logs. + +{% highlight shell %} +{% raw %} +> docker build . -t my-app +Sending build context to Docker daemon 81.92kB +Step 1/10 : FROM golang:1.12-alpine + ---> 6a17089e5a3a +Step 2/10 : RUN apk add --no-cache git + ---> Using cache + ---> 7b65bc6a6690 +Step 3/10 : WORKDIR /app/go-sample-app + ---> Using cache + ---> 8755d1490fe2 +Step 4/10 : COPY go.mod . + ---> Using cache + ---> 476d868ceddd +Step 5/10 : COPY go.sum . + ---> Using cache + ---> 3239097e9bde +[...] +{% endraw %} +{% endhighlight %} + +In a distributed build environment however, things work much differently as each build node has its own cache. If you run a pipeline on one node and then run a second build on another node everything will be recreated again because (normally) build nodes don't share any cache. + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/no-distributed-layer-cache.png" +url="/images/pipeline/caching/no-distributed-layer-cache.png" +alt="Without a distributed docker layer cache" +caption="Without a distributed docker layer cache" +max-width="60%" +%} + +In the example above if you run another build that is picked up by build node 18 all Docker filesystem layers will be recreated again even though they are already present in other nodes. + +Codefresh is one of the few CI/CD solutions that has a *distributed* Docker layer cache. This makes layer caching available to all build nodes. It doesn't matter any more which build node runs which pipeline as all of them are equal regarding their caching capabilities. + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/distributed-layer-cache.png" +url="/images/pipeline/caching/distributed-layer-cache.png" +alt="Wit a distributed docker layer cache" +caption="With a distributed docker layer cache" +max-width="60%" +%} + +With the distributed docker layer cache all build nodes are now equal. Any of the available nodes can pick your next pipeline build as all of them have access to all the previous docker filesystem layers. + +You can see if this cache is used in your [pipeline logs]({{site.baseurl}}/docs/codefresh-yaml/steps/build/): + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/distributed-docker-layer-cache.png" +url="/images/pipeline/caching/distributed-docker-layer-cache.png" +alt="Docker layer caching regardless of build node" +caption="Docker layer caching regardless of build node" +max-width="60%" +%} + +Codefresh will also automatically pass the `--cache-from` directive to docker builds with the previous successful build artifacts: + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/cache-from.png" +url="/images/pipeline/caching/cache-from.png" +alt="Distributed version of `--cache-from`" +caption="Distributed version of `--cache-from`" +max-width="60%" +%} + +To take advantage of this build cache just follow the official Docker guidelines and best practices such as + +* Download dependencies in a separate docker layer +* Put layers that will not change frequently at the top of dockerfile (e.g. OS libs) +* Put things that will change frequently at the bottom of the dockerfile (e.g. source code) +* Don't use side effects in Dockerfiles + +Basically, if your Dockerfile is already optimized on your local workstation, it should also be optimized for Codefresh. More information can be found in the official documentation: + +* [https://www.docker.com/blog/intro-guide-to-dockerfile-best-practices/](https://www.docker.com/blog/intro-guide-to-dockerfile-best-practices/) +* [https://docs.docker.com/develop/develop-images/dockerfile_best-practices/](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) + +## Docker registry caching + +This is a caching mechanism unique to Codefresh and applicable only to [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) when any of [connected Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) is used. + +Codefresh will check the internal Docker registry *before* a build step and if the exact same image is found (using the image hash), it will skip the build step completely: + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/skip-build.png" +url="/images/pipeline/caching/skip-build.png" +alt="Skipping a previously built Docker image" +caption="Skipping a previously built Docker image" +max-width="60%" +%} + +This is a very effective way to cut down the amount of time needed by pipelines but it obviously works only for Docker images that don't change often (helper images, plugins, build tools etc.) as the deployment docker images will always be different when a new git commit happens in the source code. + +You can take advantage of this mechanism by [not mixing deployment docker images with development docker images](https://codefresh.io/containers/docker-anti-patterns/). The former will change all the time, while the latter should be recreated less often. + +## Traditional build caching + +If you have read the [introduction to pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) page you will already be familiar with the shared volume that is automatically mounted on all pipeline steps. This volume is not only used for data exchange between steps of the same pipeline, but is also stored/fetched for each subsequent build as well. + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/pipeline-volume-caching.png" +url="/images/pipeline/caching/pipeline-volume-caching.png" +alt="Pipeline workspace caching" +caption="Pipeline workspace caching" +max-width="90%" +%} + +This means that unlike other CI solutions where you have to manually describe what folder you wish to cache, in Codefresh **everything that exists in `/codefresh/volume` and its subfolders is automatically cached between different builds** of the same pipeline. The volume mounting and caching/restoring process is completely automatic. You don't need any configuration about it. + +The main choice that you have is which files to place on the volume. For example, Node.js uses the folder `node_modules` for its dependencies which are placed under the project folder [which is automatically placed under the volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code). So all contents of `node_modules` will be cached by default without any further action on your part. + +>Note that if you are using [Codefresh on-prem]({{site.baseurl}}/docs/administration/codefresh-on-prem/), this kind of caching is not available for the built-in runtime and you need to use the [Codefresh Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) +with your own runtime to activate volume caching. + +The simplest way to see this caching mechanism in action is this pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + write_sample_file: + title: Writing to shared volume + image: alpine:3.10.3 + commands: + - date >> /codefresh/volume/sample.txt + read_sample_file: + title: Reading from shared volume + image: alpine:3.10.3 + commands: + - cat /codefresh/volume/sample.txt +{% endraw %} +{% endhighlight %} + +If you run this pipeline multiple times you will see multiple entries in the file `sample.txt`. + +>Note that if you run concurrent builds too quickly after one another, the Codefresh Volume will refresh [from scratch]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/#issues-with-parallel-builds-and-parallel-pipelines) instead of being cached between builds. + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/codefresh-shared-volume.png" +url="/images/pipeline/caching/codefresh-shared-volume.png" +alt="Shared volume after 3 builds of the same pipeline" +caption="Shared volume after 3 builds of the same pipeline" +max-width="60%" +%} + +Notice also the complete lack of `volume` directives in the `codefresh.yml` file. The pipeline volume is mounted and cached/restored by Codefresh with no configuration on your part. + +Some important points on this caching mechanism: + +* The volume is handled and managed by Codefresh in a completely transparent manner. You **DO NOT** need any `volume` directives in your pipelines to take advantage of it. The volume is even present in [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for integration tests. +* On each build the [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) will purge/delete everything that is not placed in `.gitignore`. So make sure that your `.gitignore` files contain all the things that you want to see cached (e.g. `node_modules`) +* If you use the SAAS version of Codefresh, volumes will be reused across all your account pipelines. If you use the On-prem or Hybrid version of Codefresh, pipeline volumes can be scoped to different pipelines or triggers as well +* You need at least one build of your pipeline in order for the cache mechanism to take any effect. +* The volume is **NOT available** in [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080). There is no folder `/codefresh/volume` inside a Dockerfile for you to access. +* This is the only caching mechanism that is not related to Docker images. So if you compile/package a traditional application with Codefresh that is not packaged as a Docker image this is the only way to get faster builds. + +See also a [full example]({{site.baseurl}}/docs/yaml-examples/examples/shared-volumes-between-builds/) that uses the volume at [https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds](https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds). + +### Caching folders which are outside your project folder + +By default if you checkout a Git project named `foo`, the source code [is placed under]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) `/codefresh/volume/foo`. This means that with zero configuration the following things are cached: + +* your source code of `foo` project +* all dependencies under the project folder (e.g. `foo/node_modules`) +* all project logs, test results that are inside the project module. + +Everything else found in external folders is NOT cached by default. So if you have things in folders such as `/root`, `/tmp/`, `/home/`, `/var/` that you need to cache you need to manually copy them to the volume. + +In practice, this means that you need to look at the documentation of your build system and test framework and make sure that all folders you want cached are placed under the Codefresh volume. This is a typical pattern with Java applications. + + * For Maven use `mvn -Dmaven.repo.local=/codefresh/volume/m2_repository package` as shown in the [example]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/). + * For Gradle use `gradle -g /codefresh/volume/.gradle -Dmaven.repo.local=/codefresh/volume/m2` as explained in the [example]({{site.baseurl}}/docs/learn-by-example/java/gradle/). + * For SBT use `-Dsbt.ivy.home=/codefresh/volume/ivy_cache`. + * For Pip use `pip install -r requirements.txt --cache-dir=/codefresh/volume/pip-cache` as shown in the [example]({{site.baseurl}}/docs/learn-by-example/python/django/) + * For Golang pass an environment variable `GOPATH=/codefresh/volume/go` to the freestyle step that is running go commands + * For Rust pass an environment variable `CARGO_HOME=/codefresh/volume/cargo` to the freestyle step that is running rust/cargo commands + + This is only needed for traditional applications that are not dockerized. If you already use Docker containers the previous caching mechanisms are already enough. + +### Issues with parallel builds and parallel pipelines + +Codefresh supports two forms of parallelism, parallel steps within the same pipeline and parallel pipelines (as well as concurrent builds). + +All parallel steps inside the same pipeline use the same volume. Codefresh [does not perform any conflict detection in that case]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#shared-codefresh-volume-and-race-conditions). + +For concurrent builds of the same pipeline, notice that if you make too many commits very fast (triggering a second build while the previous one is still running), Codefresh will allocate a brand new volume for the subsequent builds. This will force all builds to start with a clean shared volume, resulting in longer build times. Be sure to set your [build termination settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) correctly. + +{% include image.html +lightbox="true" +file="/images/pipeline/caching/concurrent-build-caching.png" +url="/images/pipeline/caching/concurrent-build-caching.png" +alt="Concurrent build caching" +caption="Concurrent build caching" +max-width="80%" +%} + +The diagram above shows the following sequence of events: + +1. The first build of a pipeline is triggered. Codefresh allocates a brand new volume and automatically mounts is as a workspace at `/codefresh/volume`. +1. The first build runs and stores artifacts on the volume +1. The first build finishes. Codefresh stores the volume in the cache +1. A second build is triggered for the same pipeline and same git branch. Codefresh sees that there is already a volume in the cache and passes it to the second build. The second build correctly finds all artifacts in the cache +1. *Before the second build finishes*, a third build is triggered. +1. The pipeline volume is still locked by the second build and Codefresh cannot use it in the third build. Codefresh allocates a **brand new volume** that has no artifacts at all and passes it to the third build +1. The second build finishes and its volume is saved into cache +1. The third build finishes and its volume is saved into cache *overwriting* the volume of the second build. +1. If a fourth build starts it will use the volume from the third build since this was the last saved volume. + + + +## Codefresh cache size and eviction policy + +If you use the SAAS version of Codefresh, then you don't have any control of cache policies. +The SAAS version is fully controlled by Codefresh personnel and the cache policies in place might clear caches sooner than you think. + +If you run a pipeline very infrequently it is possible to suffer many cache misses. If you also use obscure Docker images you might see them downloaded again and again. + +If you run the [hybrid or on-prem versions]({{site.baseurl}}/docs/enterprise/installation-security/) of Codefresh, then your system administrator is responsible for fine-tuning the cache settings. + +## What to read next + +* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Parallel pipelines]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) diff --git a/_docs/pipelines/pipelines.md b/_docs/pipelines/pipelines.md new file mode 100644 index 00000000..0a351dd5 --- /dev/null +++ b/_docs/pipelines/pipelines.md @@ -0,0 +1,308 @@ +--- +title: "Creating Pipelines" +description: "How to define Pipelines in Codefresh" +group: configure-ci-cd-pipeline +redirect_from: + - /docs/pipeline + - /docs/pipeline/ + - /docs/pipelines + - /docs/pipelines/ + - /docs/pipelines/introduction/ + - /docs/pipelines/introduction + - /docs/inline-yaml-editing + - /docs/inline-yaml-editing/ +toc: true +--- + +Before reading this page make sure that you are familiar with the theory behind Codefresh pipelines at the [introduction page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). + +## Pipeline Concepts + +The aim of Codefresh pipelines is to have re-usable sequences of steps that can be used for different applications (or micro-services) via the use of git triggers. + +All the main concepts are shown below: + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/concepts.png" +url="/images/pipeline/create/concepts.png" +alt="Pipeline concepts" +caption="Pipeline concepts" +max-width="60%" +%} + +* **Projects**: the top-level concept in Codefresh. You can create projects to group pipelines that are related. In most cases a single project will be a single application (that itself contains many micro-services). You are free to use projects as you see fit. For example, you could create a project for a specific Kubernetes cluster or a specific team/department. + +* **Pipelines**: each project can have multiple pipelines. Pipelines that belong to a single project are easily managed all together. It is also very easy to create a new pipeline in a project by copying an existing pipeline. Notice that unlike other CI solutions a pipeline in Codefresh is **NOT** tied to a specific git repository. You should try to make your pipelines generic enough so that they can be reused for similar applications even when they exist in different git repositories (a fairly typical setup for microservices). + +* **Pipeline Steps**: each pipeline has a definition that defines the [pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) that are executed each time this pipeline is triggered. The definition of a pipeline is described in a special [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file. The `codefresh.yml` file can be fetched from the same repository of the source code, from a completely different repository or even defined in-place in the Codefresh pipeline editor. Again, notice that it is possible to have a pipeline that checks out its source code from git repository A, but actually defines its steps in a `codefresh.yml` file that is fetched from git repository B. + +* **Triggers**: each pipeline can have zero, one, or more [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/). Codefresh supports several kinds of triggers such as Git, Cron or Docker push triggers. Triggers that happen with Git webhooks can come from the same git repository that contains the git code **OR** any other completely different repository. Triggers are the linking medium between a pipeline and a git repository. You can have a pipeline with many triggers so it will be executed when a code change happens to any of them. + +With these basic building blocks, you can define many complex workflows. In particular, it is very easy in Codefresh to create a scenario where: + +1. A pipeline is launched because a trigger exists for Git repository A +1. The pipeline reads its `codefresh.yml` file from Git repository B +1. The pipeline clones source code from Git repository C (and starts packaging/compiling it) + +Of course, it also possible to have a simpler scenario where the trigger, the pipeline steps and the source code of the application are all defined for the same GIT repository. + + +## Creating New Pipelines + +You can create new projects by clicking on *Projects* in the left sidebar and then selecting the *New Project* button on the top right corner. A dialog will appear that will ask you for the project name and optional tags that you can use for [access control]({{site.baseurl}}/docs/enterprise/access-control/). + +Once you are inside the project view you can start editing pipelines with a UI environment that works similar to a traditional IDE. + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/pipeline-manager.png" +url="/images/pipeline/create/pipeline-manager.png" +alt="Pipeline manager" +caption="Pipeline manager" +max-width="70%" +%} + +1. On the top left you can see your current project. You can also change it by clicking on the drop-down on the top left corner. + +1. On the left side of the screen you can see all pipelines that currently belong to this project. Click on each one to edit it. +On the bottom part of this panel the *New pipeline* button allows you to create a new pipeline on the same project either from scratch +or by copying an existing one from the same project or a completely different project. + +1. The name of the currently edited pipeline is shown at the top of the window. + +1. The main window shows the definition of the current pipeline. The screenshot shows the inline editor but pipelines can also be defined from external files (checked into source control) as explained later. + +1. The right part of the window shows extra settings for this pipeline such as [premade steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/) and launch variables/parameters. + + + + +### Using the Inline Pipeline Editor + +When first creating a pipeline you will see an inline editor that allows you to define the [pipeline yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) right there in the Codefresh UI. This is great when you are starting a new project because it offers you really quick feedback. You can edit the yml steps, run a build, edit again, run a build and so on. + + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/inline-editor.png" +url="/images/pipeline/create/inline-editor.png" +alt="Inline Pipeline editor" +caption="Inline Pipeline editor" +max-width="60%" +%} + +On the top right of the panel you have additional controls: + +* The *import* button allows you to bring a `codefresh.yml` from your local workstation into the editor +* The *comment* button allows you to quickly comment/uncomment the currently selected text. The hotkey `Ctrl-/` also performs the same action +* The *formatting* button enriches the editor with special symbols for line breaks, spaces and tabs. This allows you to easily fix common formatting errors +* The *copy* button quickly copies the **whole** pipeline text in your clipboard +* You can use `Ctrl-]` and `Ctrl-[` to change indentation of the current line (use the Command key instead on MacOsX) + + +Notice that in the editor you can expand/collapse individual yaml blocks using the arrow triangles on the left of each blocks. The initial pipeline presented in the editor is suggested by Codefresh according to the contents of your Git repository. + +> You can also see the suggested Codefresh pipeline for any public git repository by using the [analyze option](https://codefresh-io.github.io/cli/analyzer/) of the Codefresh CLI. + + +## Loading codefresh.yml from Version Control + +Working with the inline editor is very convenient in the beginning, but it makes your pipeline definition only exist within the Codefresh UI and therefore goes against the basic principles of [infrastructure as code](https://en.wikipedia.org/wiki/Infrastructure_as_Code). Once you are happy with how your pipeline works you should commit it to a Git repository (which can be the same one that has the source code of the application or a completely different one). + +You can click on the *Inline YAML* header and switch it to *Use YAML from URL* or *Use YAML from Repository*. + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/pipeline-from-internal-repo.png" +url="/images/pipeline/create/pipeline-from-internal-repo.png" +alt="Pipeline from internal repo" +caption="Pipeline from internal repo" +max-width="60%" +%} + +You can then copy and paste a URL to a raw Codefresh YAML file. This will allow you to load a Codefresh YAML from any public URL. Notice that a raw URL is needed in the case of GitHub. + +As an example, instead of using `https://github.com/codefresh-contrib/example-voting-app/blob/master/codefresh.yml` you should enter `https://raw.githubusercontent.com/codefresh-contrib/example-voting-app/master/codefresh.yml` + +## Pipeline Settings + +Once you create your pipeline you can also click on the top tab called *Settings* for some extra parameters. + +### General + +- **Pipeline Name**: the name of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) +- **Pipeline ID**: the ID of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) +> Note that the Pipeline Name and ID are interchangeable when working with the Codefresh CLI +- **Pipeline Description**: a freetext pipeline description +- **Pipeline Tags**: One or more tags used for [access control]({{site.baseurl}}/docs/enterprise/access-control/) +- **Public Build Logs**: If enabled, the builds of this pipeline will be [viewable by users without a Codefresh account]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/#public-build-logs +) +- **Template**: Convert this pipeline to a template (see the next section for details on templates) +- **Badges**: simple images that show you the last [build status]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) + +### Policies + +- **Pipeline Concurrency**: the maximum number of concurrent builds (0-14 or unlimited) -- set this when your pipeline has only one trigger + > A Pipeline Concurrency of **0** freezes execution of the pipeline, switching it to maintenance mode. Use this concurrency setting to modify existing pipelines and freeze execution until you complete the changes. +- **Trigger Concurrency**: the maximum number of concurrent builds per trigger (1-15 or unlimited) -- set this when your pipeline has multiple triggers +- **Branch Concurrency**: the maximum number of concurrent builds per branch (1-15 or unlimited) -- set this when your pipeline can build different branches +- **Build Termination**: various toggles for when a build from the pipeline should terminate + - Once a build is created terminate previous builds from the same branch + - Once a build is created terminate previous builds only from a specific branch (name matches a regular expression) + - Once a build is created, terminate all other running builds + - Once a build is terminated, terminate all child builds initiated from it +- **Pending approval volume**: choose what happens with the [pipeline volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) when a pipeline is waiting for [approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) + - Keep the volume available + - Discard the volume + - Honor the option defined globally in your Codefresh account +- **Pending approval concurrency limit effect**: decide if a build that is pending approval [counts against]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#define-concurrency-limits) the concurrency limits or not + - Builds in pending approval will **not** be counted when determining the concurrency limit for a pipeline + - Builds in pending approval will **be** counted when determining the concurrency limit for a pipeline + - Honor the option defined globally in your Codefresh account + +The **Pipeline and Trigger Concurrency** limits are very important as they allow you to define how many instances of a pipeline can run in parallel when multiple commits or multiple pull requests take place. + +> Notice that these limits are *unrelated* to [parallelism within a single pipeline]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/). + +Some common scenarios are: + +* a pipeline that uses a shared resource such as a database or queue and you want to limit how many pipelines can access it +* a pipeline that deploys to a single production environment (in most cases you only want one active pipeline touching production + +The **Build Termination** settings are useful for pipelines where you commit too fast (i.e. faster then the actual runtime of the pipeline). +All these settings allow you to lesser the build instance for pipelines when too many triggers are launched at the same time. +You will find them very useful in cases where too many developers are performing small commits and builds take a long time to finish (i.e. build takes 10 minutes to finish and developers perform multiple pushes every 2 minutes) + +Some common scenarios are: + +* You are interested only on the latest commit of a branch. If pipelines from earlier commits are still running you want to terminate them. +* You don't want to wait for children pipelines to finish (i.e. when a pipeline calls another pipeline) or when a new build starts for a parent pipeline. + +For the volume behavior during approvals, notice that if [you keep the volume available]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) on the pipeline while it is waiting for approval it will still count as "running" against your pricing tier limit. + +### External Resources + +In a big organization you might have some reusable scripts or other resources (such as Dockerfiles) that you want to use in multiple pipelines. Instead of fetching them manually in freestyle steps you can simply define them as *external resources*. When a pipeline runs, Codefresh will fetch them automatically and once the pipeline starts the files/folders will already be available in the paths that you define. + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/external-resources.png" +url="/images/pipeline/create/external-resources.png" +alt="Bringing external resources into a pipeline" +caption="Bringing external resources into a pipeline" +max-width="80%" +%} + +Currently Codefresh supports the automatic fetching of files or folders from another Git repository. To create an external resource click the *Add Resource* button and choose: + +* The Git repository that contains the files/folder you wish to bring in the pipeline workspace +* The branch from the Git repository that contains the files/folders you wish to bring in the pipeline workspace +* The source folder in the GIT repo (use relative path) +* The target folder in the pipeline workspace where the file folder will be copied to (use absolute path) + +Once the pipeline starts, all files will be available to all freestyle steps in the paths mentioned in the target folder field. +You can define multiple external resources in a single pipeline. + +### Runtime + +- **Runtime Environment**: (by default this is set to SaaS) +- **Runtime OS**: (by default this is set to Linux) +- **Resources Size**: + - Small (recommended for 1-2 concurrent steps) + - Medium (recommended 3-4 steps) + - Large (recommended 5-6 steps) + +## Using Pipeline Templates + +Codefresh also supports the creation of pipeline "templates" which are blueprints for creating new pipelines. To enable the creation of pipelines from templates first visit the global pipeline configuration at [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings) and toggle the *Enable Pipeline Templates* button. + +The easiest way to create a new template is by clicking the "3 dots menu" on the pipeline name: + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/create-template-menu.png" +url="/images/pipeline/create/create-template-menu.png" +alt="The template menu" +caption="The template menu" +max-width="30%" +%} + +From the dialog you can select if you want to copy this pipeline as a brand new template, or simply convert the pipeline itself to a template: + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/template-dialog.png" +url="/images/pipeline/create/template-dialog.png" +alt="The template dialog" +caption="The template dialog" +max-width="80%" +%} + +Once the template is created, you can edit it like any other pipeline. Pipeline templates are marked with the `template` tag and also have a special mark in the pipeline menu: + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/template-tag.png" +url="/images/pipeline/create/template-tag.png" +alt="template identification" +caption="template identification" +max-width="90%" +%} + +Now when you create a new pipeline, you can also select which pipeline template will be used as an initial pipeline definition: + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/use-template.png" +url="/images/pipeline/create/use-template.png" +alt="Using a template" +caption="Using a template" +max-width="70%" +%} + +>Notice that templates only take effect during pipeline creation. Changing a template afterwards, has no effect on pipelines that are already created from it. + +You can also quickly convert a pipeline to a template, by visiting the pipeline settings and clicking the *template* button under the *General* tab. + + +## Pipelines that do not belong to any project + +Although we recommend adding all your pipelines to a project, this is not a hard requirement. You can create pipelines that do not belong to a project from the *Pipelines* section on the left sidebar. +If you have a Codefresh account created before May 2019 you might already have several pipelines that are like this. + +If you change your mind, you can also add detached pipelines (i.e. pipelines that are not part of a project) manually from the 3-dot menu that is found on the right of each pipeline. + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/add-pipeline-to-project.png" +url="/images/pipeline/create/add-pipeline-to-project.png" +alt="Changing the project of a pipeline" +caption="Changing the project of a pipeline" +max-width="90%" +%} + +Pipelines that belong to a project will mention it below their name so it is very easy to understand which pipelines belong to a project and which do not. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +* [YAML Examples]({{site.baseurl}}/docs/yaml-examples/examples/) + + + + + diff --git a/_docs/pipelines/post-step-operations.md b/_docs/pipelines/post-step-operations.md new file mode 100644 index 00000000..1d367309 --- /dev/null +++ b/_docs/pipelines/post-step-operations.md @@ -0,0 +1,117 @@ +--- +title: "Post-Step Operations" +description: "Annotate your builds and run extra steps" +group: codefresh-yaml +redirect_from: + - /docs/post-step-operations/ +toc: true +--- +Post-step operations are a set of optional predefined processes that can be configured on any step. These operations will be executed once the step has completed. The post-step operations allow you to annotate your builds, images and pipelines with extra metadata or run other steps. + + +## Result Aware Post-Step Operations +You may execute post-step operations conditionally, based on the outcome of the step itself. + +To execute operations only when the step has completed successfully, use `on_success`: + + +{% highlight yaml %} +step_name: + ... + on_success: + ... +{% endhighlight %} + +To execute operations only when the step has failed, use `on_fail`: + + +{% highlight yaml %} +step_name: + ... + on_fail: + ... +{% endhighlight %} + +## Result Agnostic Post-Step Operations +You may execute post-step operations regardless of the outcome of the step itself. + +To execute operations regardless of the result, use `on_finish`: + + +{% highlight yaml %} +step_name: + ... + on_finish: + ... +{% endhighlight %} + +## Available Post-Step Operations + +- [Image Metadata]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) +- [Custom Annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +- [Hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) + +## Example + +Marking a Docker image with the results of unit tests: + +{% highlight yaml %} +{% raw %} +build_step: + title: Building My Docker image + type: build + image_name: my-app-image + tag: 1.0.1 + dockerfile: Dockerfile +run_tests: + title: Running unit tests + image: ${{build_step}} + commands: + - npm install + - npm run test + on_success: # Execute only once the step succeeded + metadata: + set: + - ${{build_step.imageId}}: + - unit_tests: passed +{% endraw %} +{% endhighlight %} + +## Running other steps + +If you want to run another step in the pipeline when another step fails or succeeds you need to use [conditional execution of steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) and the `fail_fast` property. You can also use [step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) for dedicated post step actions. + +{% highlight yaml %} +{% raw %} +run_tests: + title: Running unit tests + image: node:11 + fail_fast: false + commands: + - npm install + - npm run test +print_error_message: + image: alpine:latest + title: Marking pipeline status + commands: + - echo "Unit tests failed" + when: + condition: + all: + myCondition: run_tests.result == 'failure' +{% endraw %} +{% endhighlight %} + +In this example the step `print_error_message` will only run if step `run_tests` has failed. + +See also [advanced workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#single-step-dependencies) and [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/). + +## What to read next + +* [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +* [Condition Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +* [Working Directories]({{site.baseurl}}/docs/codefresh-yaml/working-directories/) +* [Annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) + + diff --git a/_docs/pipelines/running-pipelines-locally.md b/_docs/pipelines/running-pipelines-locally.md new file mode 100644 index 00000000..f27f166f --- /dev/null +++ b/_docs/pipelines/running-pipelines-locally.md @@ -0,0 +1,126 @@ +--- +title: "Running pipelines locally" +description: "How to run Codefresh pipelines on your workstation" +group: configure-ci-cd-pipeline +toc: true +redirect_from: + - /docs/troubleshooting/common-issues/debugging-codefresh-builds-locally/ + - /docs/troubleshooting/common-issues/access-and-debug-the-pipeline-volume-image/ +--- + +Codefresh can run your pipelines locally. This is very handy when you need to debug a pipeline, or when you want to do quick changes to the [codefresh.yml file]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) with the fastest turn-around time possible. + +## Prerequisites + +You need to have Docker installed on your local workstation. You can follow the [official instructions](https://docs.docker.com/install/) to install it. Notice that if you use Linux, the Docker version offered by your native +package manager is not always the latest version. + +Once docker is installed, check that it runs correctly with: + +``` +docker run hello-world +``` + +You should get a short welcome message. + +>At the time of writing local builds can only run on Linux and Mac workstations. We are working to remove this limitation and allow developers with Windows machines to also run Codefresh pipelines locally. + +Then install the [open-source Codefresh CLI](https://codefresh-io.github.io/cli/installation/) and [setup authentication](https://codefresh-io.github.io/cli/getting-started/) with your Codefresh account. + +Once this is done check that your account is locally accessible by running + +``` +codefresh get pipelines +``` + +You should see a long list with your pipelines on the terminal output. + +## Running a pipeline locally + +The Codefresh Command Line Interface (CLI) comes with a [run parameter](https://codefresh-io.github.io/cli/pipelines/run-pipeline/) that allows you to trigger pipelines externally (outside the Codefresh UI). + +Normally, if you run a pipeline this way the CLI will just trigger it remotely (the pipeline itself will still run in the Codefresh infrastructure). + +You can pass however the `--local` option, and this will instruct the CLI to automatically: + +1. Download the Codefresh build engine locally to your workstation (which itself is a docker image at [codefresh/engine](https://hub.docker.com/r/codefresh/engine)) +1. Run the build locally using the Codefresh engine on your workstation +1. Print all build logs to your terminal + +Note that the engine has transparent network access to all the other settings in your Codefresh account and therefore will work exactly the same way as if it was run on Codefresh infrastructure (e.g. use the connected Docker registries you have setup in the UI) + +Here is a full example: + +``` +codefresh run francisco-codefresh/jan_19/my-basic-pipeline --local -b master -t my-trigger +``` + + + +### Keeping the pipeline volume in the local workstation + +If you are familiar with +[how Codefresh pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) you should know about the unique docker volume that is automatically shared between all pipeline steps. + +This volume (which also includes the project folder) makes data sharing between all steps very easy (e.g. with thing such as test reports or binary dependencies). + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/codefresh-volume.png" +url="/images/pipeline/introduction/codefresh-volume.png" +alt="Codefresh volume" +caption="All steps share the same volume" +max-width="80%" +%} + +By default, if you run a Codefresh pipeline locally, this shared volume will automatically be discarded at the end of the build. You can still keep the volume after the build by adding the `--local-volume` parameter in your [run command](https://codefresh-io.github.io/cli/pipelines/run-pipeline/). Here is an example: + +``` +codefresh run francisco-codefresh/jan_19/my-basic-pipeline --local --local-volume -b master -t my-trigger +``` + + +Once the build runs you will see in your terminal the path that holds the contents of the volume: + +``` +[...build logs...] +Using /Users/fcocozza/.Codefresh/francisco-codefresh/jan_19/my-basic-pipeline as a local volume. +[...more build logs] +``` + +After the build has finished you can freely explore this folder in your filesystem with any file manager. + +``` +$ ls -alh /Users/fcocozza/.Codefresh/francisco-codefresh/jan_19/my-basic-pipeline/ +total 16 +drwxr-xr-x 5 fcocozza staff 160B Jan 14 12:52 . +drwxr-xr-x 3 fcocozza staff 96B Jan 14 12:52 .. +-rwxr-xr-x 1 fcocozza staff 388B Jan 14 12:52 cf_export +-rw-rw-r-- 1 fcocozza staff 189B Jan 14 12:52 env_vars_to_export +drwxr-xr-x 5 fcocozza staff 160B Jan 14 12:52 jan_19 +``` +This way you can verify if the pipeline has access to the data you think it should have + + +### Using a custom codefresh.yml file + +The ultimate way to run a pipeline locally is to override completely the `codefresh.yml` file it uses. A pipeline by default will read its steps from the respective file in git. + +You can force it to ignore that git version of the pipeline spec and instead load a custom `codefresh.yml` from your local file-system (which might not be even committed yet). + +The extra parameter is `--yaml` in that case. +Here is a complete example + +``` +codefresh run francisco-codefresh/jan_19/my-basic-pipeline --local --local-volume --yaml=my-codefresh.yml -b master -t my-trigger +``` + +When this pipeline runs locally, it will use whatever steps exist in `my-codefresh.yml` instead of the git version. The shared data volume will also be left intact after the build is finished as explained in the previous section. + +## What to read next + + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) diff --git a/_docs/pipelines/secrets-store.md b/_docs/pipelines/secrets-store.md new file mode 100644 index 00000000..8162db01 --- /dev/null +++ b/_docs/pipelines/secrets-store.md @@ -0,0 +1,96 @@ +--- +title: "Using secrets" +description: "Use Kubernetes secrets in Codefresh" +group: configure-ci-cd-pipeline +toc: true +--- + +Once you have [connected Codefresh to your secrets storage]({{site.baseurl}}/docs/integrations/secret-storage/), you can use them in any pipeline or GUI screen. + +> Note: This feature is for Enterprise accounts only. + +## Using secrets in pipelines + +The syntax for using the secret is {% raw %}`${{secrets.NAME_IN_CODEFRESH.KEY}}`{% endraw %}. + +> Note that if you did not include the resource-name as a part of your secret store context creation, the syntax for using your secret differs slightly: +The syntax is: {% raw %}${{secrets.NAME_IN_CODEFRESH.RESOURCE-NAME@KEY}}{% endraw %} The previous KEY portion is now made of two parts separated using @, where the left side is the name of the resource in the namespace, and the right side the key in that resource. + +To use the secret in your pipeline, you have two options: + +Define it as a pipeline variable: + +{% include +image.html +lightbox="true" +file="/images/pipeline/secrets/secrets-pipeline-var.png" +url="/images/pipeline/secrets/secrets-pipeline-var.png" +alt="Secrets Pipeline Variable" +caption="Secrets stored in Pipeline Variable" +max-width="80%" +%} + +`codefresh.yaml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + step: + type: freestyle + arguments: + image: alpine + commands: + - echo $SECRET +{% endraw %} +{% endhighlight %} + +Or use it directly in your yaml + +`codefresh.yaml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + step: + type: freestyle + arguments: + image: alpine + environment: + - SECRET=${{secrets.test.key1}} + commands: + - echo $SECRET +{% endraw %} +{% endhighlight %} + + +## Using secrets in the Codefresh GUI + +You can also use secrets in the GUI screens that support them. Currently you can use secrets in: + +* Values in [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) +* Integration with [cloud storage]({{site.baseurl}}/docs/testing/test-reports/#connecting-your-storage-account) + +Where secret integration is supported, click on the lock icon and enable the toggle button. You will get a list of your connected secrets: + + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/shared-conf-secret-integration.png" +url="/images/pipeline/shared-configuration/shared-conf-secret-integration.png" +alt="Using external secrets in shared configuration values" +caption="Using external secrets in shared configuration values" +max-width="50%" +%} + +If you have already specified the resource field during secret definition the just enter on the text field the name of the secret directly, i.e. `my-secret-key`. +If you didn't include a resource name during secret creation then enter the full name in the field like `my-secret-resource@my-secret-key`. + + +## What to Read Next + +* [Shared Configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) +* [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) +* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) +* [Debugging Pipelines]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) + diff --git a/_docs/pipelines/service-containers.md b/_docs/pipelines/service-containers.md new file mode 100644 index 00000000..13adfc2e --- /dev/null +++ b/_docs/pipelines/service-containers.md @@ -0,0 +1,571 @@ +--- +title: "Service Containers" +description: "How to use sidecar services in your pipelines" +group: codefresh-yaml +toc: true +--- + +Sometimes you wish to run sidecar containers in a pipeline that offer additional services for your builds. The most common scenario is launching services such as databases in order to accommodate [integration tests]({{site.baseurl}}/docs/testing/integration-tests/). Or you might wish to launch the application itself in order to run integration tests **against** it as part of the pipeline. + +>Note that while [composition steps]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) are still supported, the recommended way to run integrations tests going forward is with service containers. The underlying implementation is shared so check the composition documentation page for more available options +and properties. + +Codefresh includes a handy mechanism (based on Docker compose) that can help you run sidecar containers along your main pipeline. Here is a very simple example. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +services: + name: my_database + composition: + my-redis-db-host: + image: redis:latest + ports: + - 6379 +steps: + my_integration_tests: + image: my-app-image + title: Running integration tests + commands: + - npm run test + services: + - my_database +{% endraw %} +{% endhighlight %} + +This pipeline will run integration tests during the freestyle step called `my_integration_tests` and at that point a Redis instance will be available at hostname `my-redis-db-host` and port 6379. Note how in this example, the service container is placed at the root of the pipeline (as opposed to inside a specific step). This ensures that the Redis instance is running for [the duration of the pipeline]({{site.baseurl}}/docs/codefresh-yaml/service-containers/#running-services-for-the-duration-of-the-pipeline). + +>Service Containers are based on Docker Compose. This document does not have the complete list of available options available. Please refer to Docker Compose versions [2](https://docs.docker.com/compose/compose-file/compose-file-v2/) and [3](https://docs.docker.com/compose/compose-file/), but not point releases such as 2.1. + + +## Viewing Service containers + +The service containers have their own output tab in Codefresh UI + +{% include image.html + lightbox="true" + file="/images/codefresh-yaml/services/services-tab.png" + url="/images/codefresh-yaml/services/services-tab.png" + alt="Output tab from extra services" + caption="Output tab from extra services" + max-width="100%" + %} + +This way it is very easy to differentiate between the output logs of the step itself and its supporting container services. + + +## Launching multiple sidecar containers + +Like Docker compose it is possible to launch multiple services this way. For example, let's say that a Java application needs both Redis and MongoDB during integration tests. Here is the respective pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +services: + name: my_extra_services + composition: + my-redis-db-host: + image: redis:latest + ports: + - 6379 + my-mongo-db-host: + image: mongo:latest + ports: + - 27017 +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-java-app" + git: github + revision: "master" + my_tests: + image: maven:3.5.2-jdk-8-alpine + title: "Running Integration tests" + commands: + - 'mvn integration-test' +{% endraw %} +{% endhighlight %} + +The Redis instance will be available through the networks at `my-redis-db-host:6379` while the MongoDB instance will run at `my-mongo-db-host:27017`. + +Instead of mentioning all your services directly in the YAML file you might also reuse an existing composition you have already defined in Codefresh by mentioning it by name. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +services: + name: my_extra_services + composition: redis_and_mongo +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-java-app" + revision: "master" + git: github + my_tests: + image: maven:3.5.2-jdk-8-alpine + title: "Unit tests" + commands: + - 'mvn integration-test' +{% endraw %} +{% endhighlight %} + +This pipeline mentions an existing composition called `redis_and_mongo`: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/existing-composition.png" +url="/images/codefresh-yaml/existing-composition.png" +alt="Using an existing composition" +caption="Using an existing composition" +max-width="70%" +%} + +This makes very easy to reuse compositions that you have already defined for other reasons [in the Codefresh UI](https://codefresh.io/docs/docs/testing/create-composition/). + + +## Running services for the duration of the pipeline + +Notice that unlike compositions, the services defined in the root of the pipeline yaml are present for the **whole** pipeline duration. They are available in all pipeline steps. This can be seen in the following example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +services: + name: my_database + composition: + my-redis-db-host: + image: redis:latest + ports: + - 6379 +steps: + my_first_step: + image: alpine:latest + title: Storing Redis data + commands: + - apk --update add redis + - redis-cli -u redis://my-redis-db-host:6379 -n 0 LPUSH mylist "hello world" + - echo finished + services: + - my_database + my_second_step: + image: alpine:latest + commands: + - echo "Another step in the middle of the pipeline" + my_third_step: + image: alpine:latest + title: Reading Redis data + commands: + - apk --update add redis + - redis-cli -u redis://my-redis-db-host:6379 -n 0 LPOP mylist + services: + - my_database +{% endraw %} +{% endhighlight %} + +This pipeline: + +1. Starts a single Redis instance +1. Saves some data in the first step on the pipeline +1. Runs an unrelated step (that itself is not using the redis instance) +1. Reads the data saved in the third steps + +If you run this pipeline you will see that that data read in the third step of the pipeline was the same one as the data saved in the first step. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/redis-example.png" +url="/images/codefresh-yaml/redis-example.png" +alt="Redis read/write example" +caption="Redis read/write example" +max-width="90%" +%} + +This means that you can easily use the extra services in different steps of a single pipeline, without relaunching them each time (which is what happens with composition steps). + +## Using sidecar services in specific steps + +It is important to understand that any services you launch in a pipeline, are sharing its memory. If for example your pipeline has 4GBs of memory and your service (e.g. a mongdb instance) consumes 1GB, then you only have 3GB available for the actual pipeline. + +It is therefore possible to a assign a service to a specific step if you don't wish to have it running for the duration of the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-java-example" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-java-app" + dockerfile: "Dockerfile" + tag: latest + my_unit_tests: + image: '${{build_image}}' + title: "Unit tests" + commands: + - 'echo start testing my app' + services: + composition: + my_redis_service: + image: 'redis:latest' + ports: + - 6379 + my_integration_tests: + image: '${{build_image}}' + title: "Integration tests" + commands: + - 'echo start testing my app' + services: + composition: + my_mongo_Service: + image: 'mongo:latest' + ports: + - 27017 +{% endraw %} +{% endhighlight %} + +In this pipeline, the Redis instance is only launched during the Unit test step, while the MongoDB service is active only during integration tests. + +You can also use a `docker-compose.yml` file that you might have in your git repository. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-java-example" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-java-app" + dockerfile: "Dockerfile" + tag: latest + my_unit_tests: + image: '${{build_image}}' + title: "Unit tests" + commands: + - 'echo start testing my app' + services: + composition: + my_redis_service: + image: 'redis:latest' + ports: + - 6379 + my_integration_tests: + image: '${{build_image}}' + title: "Integration tests" + commands: + - 'echo start testing my app' + services: + composition: 'docker-compose.yml' +{% endraw %} +{% endhighlight %} + +Note that in this case the `docker-compose.yml` file must mention [specific images](https://docs.docker.com/compose/compose-file/#image) (and not use [build properties](https://docs.docker.com/compose/compose-file/#build)). + + +## Launching a custom service + +So far all the examples of extra services used predefined docker images (i.e. Redis and Mongo). You are free however to launch any custom docker image you have already created or even the main application of the pipeline. + +This happens by mentioning a build step as a service image. Here is an example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-back-end" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-backend-app" + tag: latest + dockerfile: "Dockerfile" + run_integration_tests: + title: Test backend + image: 'my-front-end:latest' + commands: + - 'curl my_backend_app:8080' + - 'echo Backend is up. Starting tests' + - npm run integration-test + services: + composition: + my_backend_app: + image: '${{build_image}}' + ports: + - 8080 +{% endraw %} +{% endhighlight %} + +Here a Dockerfile for a backend application is built on the spot and then is launched as sidecar container in the next step (with a hostname of `my_backend_app`). Notice that the `image` property in the sidecar service actually refers to a [Codefresh variable]({{site.baseurl}}/docs/codefresh-yaml/variables/) that holds the name of the build step. + +We then run a `curl` command against the sidecar container to verify the correct health of the application. This is a great way to run integration tests against multiple micro-services. + + +## Checking readiness of a service + +When you launch multiple services in your pipelines, you don't know exactly when they will start. Maybe they will be ready once you expect them, but maybe they take too long to start. For example if you use a MySQL database in your integration tests, your integration tests need to know that the database is actually up before trying to use it. + +This is the same issue that is present in [vanilla Docker compose](https://docs.docker.com/compose/startup-order/). You can use solutions such as [wait-for-it](https://github.com/vishnubob/wait-for-it) to overcome this limitation, but Codefresh offers a better way in the form of *service readiness*. + +With a readiness block you can guarantee that a sidecar service will be actually up before the pipeline will continue. Here is an example: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-back-end" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-backend-app" + tag: latest + dockerfile: "Dockerfile" + run_integration_tests: + title: Test backend + image: 'my-front-end:latest' + commands: + # Backend is certainly up at this point. + - npm run integration-test + services: + composition: + my_backend_app: + image: '${{build_image}}' + ports: + - 8080 + readiness: + image: 'byrnedo/alpine-curl' + timeoutSeconds: 30 + commands: + - "curl my_backend_app:8080" +{% endraw %} +{% endhighlight %} + + +This is an improvement over the previous example because the healthcheck of the back-end is managed by Codefresh. The added `readiness` block makes sure that the back-end service is actually up before the integration tests start by using a `curl` command to check that `my_backend_app:8080` is up and running. Codefresh will run the commands defined in the `readiness` in a loop until they succeed. You are free to use any of your favorite commands there (ping, curl, nc etc) that check one or more services. We also define a timeout for the healthcheck. The `readiness` block supports the following options: + +* `periodSeconds`: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. +* `timeoutSeconds`: Number of seconds after which the probe times out. Defaults to 10 seconds. Minimum value is 1. +* `successThreshold`: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for readiness. Minimum value is 1. +* `failureThreshold`: failureThreshold times before giving up. In case of readiness probe the Pod will be marked Unready. Defaults to 3. Minimum value is 1 + +If you know already how [Kubernetes readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) work, then these settings will be very familiar to you. + +Here is another example where we use the `pg_isready` command to make sure that a PostgreSQL database is ready to accept connections +before we run the integration tests. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-rails-app" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-rails-app" + tag: "latest" + dockerfile: "Dockerfile" + run_integration_tests: + image: '${{build_image}}' + commands: + # PostgreSQL is certainly up at this point + - rails db:migrate + - rails test + services: + composition: + my_postgresql_db: + image: postgres:latest + ports: + - 5432 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: 'postgres:latest' + commands: + - "pg_isready -h my_postgresql_db" +{% endraw %} +{% endhighlight %} + +In summary `readiness` make sure that your services are actually up before you use them in a Codefresh pipeline. + +## Preloading data to databases + +A very common scenario when using databases in integration tests is the need to preload some test data in the database. +While you could do that in a normal pipeline step, sidecar services have a special `setup` block for this purpose. This way not only you can make sure that the database is up (using the `readiness` property explained in the previous section) but also that it is preloaded with the correct data. + +To use this capability add a `setup` block in your pipeline service container: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "kostis-codefresh/my-rails-app" + revision: "master" + git: github + build_image: + title: "Building Docker Image" + type: "build" + image_name: "my-rails-app" + tag: "latest" + dockerfile: "Dockerfile" + run_integration_tests: + image: '${{build_image}}' + commands: + # PostgreSQL is certainly up at this point and has the correct data + - rails test + services: + composition: + my_postgresql_db: + image: postgres:latest + ports: + - 5432 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: 'postgres:latest' + commands: + - "pg_isready -h my_postgresql_db" + setup: + image: 'postgres:latest' + commands: + - "wget my-staging-server.exaple.com/testdata/preload.sql" + - "psql -h my_postgresql_db < testdata/preload.sql" +{% endraw %} +{% endhighlight %} + +Notice that in that case the sequence of events is the following + +1. Codefresh will launch the container image(s) mentioned in the composition block +1. The `readiness` block will run until the service image is ready to accept connections +1. The `setup` block will run and preload data or setup any custom commands you have placed in the property +1. The actual pipeline step will now run with the service container attached in the same network. + +## Accessing containers via localhost + +Ideally, your application should be able to access other services by other DNS names that are fully configurable (this is a very good practice for [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) as well). + +Sometimes, however, and especially in legacy applications, your application might be hardcoded to look at other services at `localhost`. +In that case, you can use the attribute `shared_host_network: true` on the services definition. Now all linked containers can access each other's services via localhost. +When `composition: ./docker-compose.yml` is used, this parameter is supported only in on-premises and hybrid environments. In cloud environments, for security reasons, this parameter is ignored. + +Here is an example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_first_step: + image: goodsmileduck/redis-cli + title: Storing Redis data + commands: + - apk add curl + - 'redis-cli -u redis://localhost:6379 -n 0 LPUSH mylist "hello world"' + - 'curl http://localhost:80' + - echo finished + services: + shared_host_network: true + composition: + my_redis_service: + image: 'redis:latest' + my_nginx: + image: nginx +{% endraw %} +{% endhighlight %} + +You can also do the same thing with top level services: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +services: + name: my_database + shared_host_network: true + composition: + my_redis_service: + image: 'redis:latest' + my_nginx: + image: nginx +steps: + my_first_step: + image: goodsmileduck/redis-cli + title: Storing Redis data + commands: + - apk add curl + - 'redis-cli -u redis://localhost:6379 -n 0 LPUSH mylist "hello world"' + - 'curl http://localhost:80' + - echo finished + services: + - my_database +{% endraw %} +{% endhighlight %} + +Note: we do recommend you only use this option as a last resort. You should not hardcode "localhost" as a requirement in your services as +it adds extra constraints with integration tests (and especially with dynamic test environments). + + +## Limitations + +Service containers are not compatible with [custom pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/#limitations-of-custom-plugins). + + + + +## What to read next + +* [Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +* [Integration test with database]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-database/) +* [Creating Compositions]({{site.baseurl}}/docs/on-demand-test-environment/create-composition/) + + + + + + + + diff --git a/_docs/pipelines/shared-configuration.md b/_docs/pipelines/shared-configuration.md new file mode 100644 index 00000000..5f47aff6 --- /dev/null +++ b/_docs/pipelines/shared-configuration.md @@ -0,0 +1,265 @@ +--- +title: "Shared configuration" +description: "How to keep your pipelines DRY" +group: configure-ci-cd-pipeline +toc: true +--- + +After creating several pipelines in Codefresh you will start to notice several common values between them. Common examples are access tokens, environment URLs, configuration properties etc. + +Codefresh allows you to create those shared values in a central place and then reuse them in your pipelines +avoiding the use of copy-paste. + +You can share: + +* Environment parameters (easy) +* Helm values (easy) +* Any kind of YAML data (advanced) + + +## Creating shared configuration + +From the left sidebar click *Account settings* to enter your global settings. Then choose *Shared Configuration* from the left menu. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/shared-configuration.png" +url="/images/pipeline/shared-configuration/shared-configuration.png" +alt="Creating shared configuration snippets" +caption="Creating shared configuration snippets" +max-width="50%" +%} + +You can create four types of shared configuration: + +* **Shared Configuration**: for environment variables +* **Shared Secret**: for encrypted environment variables of sensitive data (access tokens, etc.) +* **YAML**: for Helm values or any other generic information +* **Secret YAML**: for above, but encrypts the contents + +>RBAC is supported for all types of shared configurations. + +You can create as many shared snippets as you want (with unique names). + +### Using external secrets as values + +Note that the default "shared secrets" and "secret yaml" entities use the built-in secret storage of Codefresh. You can also +use any [external secrets that you have defined]({{site.baseurl}}/docs/integrations/secret-storage/) (such as Kubernetes secrets), by using the normal entities and then clicking on the lock icon that appears. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/shared-conf-secret-integration.png" +url="/images/pipeline/shared-configuration/shared-conf-secret-integration.png" +alt="Using external secrets in shared configuration values" +caption="Using external secrets in shared configuration values" +max-width="50%" +%} + +If you have already specified the resource field during secret definition the just enter on the text field the name of the secret directly, i.e. `my-secret-key`. +If you didn't include a resource name during secret creation then enter the full name in the field like `my-secret-resource@my-secret-key`. + +### Level of access + +For each set of values you can toggle the level of access by [non-admin users]({{site.baseurl}}/docs/administration/access-control/#users-and-administrators). If it is off, users will **not** be able to use the [CLI](https://codefresh-io.github.io/cli/) or [API]({{site.baseurl}}/docs/integrations/codefresh-api/) +to access these [values](https://codefresh-io.github.io/cli/contexts/). If it is on, all users from all your Codefresh teams will be able to access this set of values +with CLI commands or API calls. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/shared-config-access.png" +url="/images/pipeline/shared-configuration/shared-config-access.png" +alt="Allow access to non-admin users" +caption="Allow access to non-admin users" +max-width="60%" +%} + +We recommend that you disable access for all values of type *shared secret* and *secret YAML* unless your organization has different needs. + + +## Using shared environment variables + +Each pipeline has a set of environment variables that can be defined in the *Workflow* screen. +To import a shared configuration open the pipeline editor, and from the tabs on the right side select *VARIABLES*. Then click the gear icon to *Open Advanced Options*: + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/environment-variables.png" +url="/images/pipeline/shared-configuration/environment-variables.png" +alt="Pipeline environment variables" +caption="Pipeline environment variables" +max-width="50%" +%} + +To use your shared configuration, click the *Import from shared configuration* button and select the snippet from the list: + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/import-variables.png" +url="/images/pipeline/shared-configuration/import-variables.png" +alt="Importing shared configuration" +caption="Importing shared configuration" +max-width="50%" +%} + +Once you click *Add* the values from the shared configuration will be appended to the ones +you have in your pipelines. In case of similar values the shared configuration will follow the [precedence rules]({{site.baseurl}}/docs/codefresh-yaml/variables/#user-provided-variables). + + +## Using shared Helm values + +To use a shared YAML snippet for Helm values you can install a new Helm chart either from: + +* The [Helm chart list]({{site.baseurl}}/docs/new-helm/add-helm-repository/#install-chart-from-your-helm-repository) +* The [Helm environment board]({{site.baseurl}}/docs/new-helm/helm-environment-promotion/#moving-releases-between-environments). + +In both cases, when you see the Helm installation dialog you can import any of your YAML snippets +to override the default chart values. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/helm-import.png" +url="/images/pipeline/shared-configuration/helm-import.png" +alt="Importing Helm values" +caption="Importing Helm values" +max-width="50%" +%} + +From the same dialog you can also create a brand-new shared configuration snippet of type YAML. +Not only it will be used for this Helm chart, but it will be added in your global shared configuration as well. + +## Using values from the Shared Configuration in your Helm step + +Additionally, you can define shared variables in your account settings and reuse those across your Helm steps, and specifically, in your [custom Helm values](https://codefresh.io/docs/docs/new-helm/using-helm-in-codefresh-pipeline/#helm-values). + +Under *Account Setting* > *Shared Configuration*, add the variable to your shared configuration. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/helm-shared-variables.png" +url="/images/pipeline/shared-configuration/helm-version-shared.png" +alt="Adding shared configuration variables" +caption="Adding shared configuration variables" +max-width="50%" +%} + +Go to the workflow of the Codefresh pipeline to which you want to add the variable. Then select *variables* from the right sidebar. *Open advanced configuration* and select *Import from shared configuration*. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/environment-variables.png" +url="/images/pipeline/shared-configuration/environment-variables.png" +alt="Pipeline environment variables" +caption="Pipeline environment variables" +max-width="50%" +%} + +This will allow you to add shared variables. + +{% include +image.html +lightbox="true" +file="/images/pipeline/shared-configuration/shared-helm-variables.png" +url="/images/pipeline/shared-configuration/shared-helm-variables.png" +alt="Shared helm variable" +caption="Shared helm variable" +max-width="50%" +%} + +Add the shared variables to your Helm step: + +{% highlight shell %} +{% raw %} +deploy: + type: "helm" + working_directory: "./react-article-display" + stage: "deploy" + arguments: + action: "install" + chart_name: "charts/example-chart" + release_name: "test-chart" + helm_version: "${{HELM_VERSION}}" + kube_context: "anais-cluster@codefresh-sa" + custom_values: + - 'pullPolicy=${{PULL_POLICY}}' +{% endraw %} +{% endhighlight %} + +The shared variables can now be used across your pipelines. + +## Sharing any kind of YAML data in pipelines + +All the snippets from shared configuration are also available as context in the [Codefresh CLI](https://codefresh-io.github.io/cli/contexts/) + +This means that you can manipulate them programmatically and read their values in the pipeline in any way you see fit. + +If for example you have a shared configuration named `my-global-config` you can easily read its contents programmatically using the CLI: + +{% highlight shell %} +$codefresh get context my-global-config --output=yaml + +apiVersion: v1 +kind: context +metadata: + default: false + system: false + name: my-global-config +type: config +spec: + type: config + data: + foo: bar +{% endhighlight %} + +### Example - custom value manipulation + +Let's say that you have a YAML segment with the following contents: + +{% highlight yaml %} +favorite: + drink: coffee + food: pizza +{% endhighlight %} + +Here is a pipeline step that is reading the yaml snippet and extracts a value + + `YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyFavoriteFoodStep: + title: Favorite food + image: codefresh/cli + commands: + - echo I love eating $(codefresh get context my-food-values --output=json | jq -r '.spec.data.favorite.food') +{% endraw %} +{% endhighlight %} + +Once the pipeline runs, you will see in the logs: + +``` +I love eating pizza +``` + +## Manipulating shared configuration programmatically + +You can also create/update/delete shared configuration via the [Codefresh CLI](https://codefresh-io.github.io/cli/) or [API]({{site.baseurl}}/docs/integrations/codefresh-api/). + +See the [context section](https://codefresh-io.github.io/cli/contexts/create-context/) in the CLI documentation. + + + +## What to read next + +* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) + diff --git a/_docs/pipelines/stages.md b/_docs/pipelines/stages.md new file mode 100644 index 00000000..aac05a2e --- /dev/null +++ b/_docs/pipelines/stages.md @@ -0,0 +1,193 @@ +--- +title: "Pipeline Stages" +description: "Grouping steps in stages for better visualization" +group: codefresh-yaml +toc: true +--- + +With Codefresh you can [create really complex pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) with any number of steps. To better visualize the pipeline, you can group several steps into a single _stage_ that will show up as a separate column in the [pipeline view]({{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/). + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/complex-pipeline.png" +url="/images/codefresh-yaml/stages/complex-pipeline.png" +alt="Complex pipeline" +caption="Complex pipeline" +max-width="70%" +%} + +In this example there are 4 pipeline stages. + +## Assigning steps to a stage. + +Stages are completely optional and for really small pipelines they are not needed at all. +By default, all pipeline steps are shown one after the other. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/linear-view.png" +url="/images/codefresh-yaml/stages/linear-view.png" +alt="Default pipeline view" +caption="Default pipeline view" +max-width="50%" +%} + +This view works ok for small pipelines, but for a big number of steps it is better to group them into pipeline *stages* like shown below: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/example.png" +url="/images/codefresh-yaml/stages/example.png" +alt="Different pipeline stages" +caption="Different pipeline stages" +max-width="80%" +%} + +The number of stages (i.e columns) and their titles is completely configurable. +To enable this view, you need to make two modifications at the `codefresh.yml` file: + +Here is the skeleton: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +stages: + - [stage-name-1] + - [stage-name-2] + +steps: + step-name: + [step-contents] + stage: [name-of-stage] + another-step: + [step-contents] + stage: [name-of-stage] + the-very-last-step: + [step-contents] + stage: [name-of-stage] +{% endhighlight %} + +As you can see the modifications needed are: + +1. To list all the stage names at the root of the pipeline file +1. To use the `stage` property on each step to assign it to a stage + +>This updated pipeline view is only a nice way to visualize the pipeline. It does not affect the order of step execution. Steps will still execute in the same order listed in the `codefresh.yml` file. If you wish to use parallel execution and advanced workflows see the [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) page. + + +## Example pipeline with several stages + +Here is a more concrete example that you can use as a starting point: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build + - scan + - integration + - deploy +steps: + step1: + stage: 'prepare' + image: node + commands: + - 'echo "Hello Step 1!"' + step2: + image: node + stage: 'prepare' + commands: + - 'echo "Hello Step 2!"' + step3: + image: node + stage: 'test' + commands: + - 'echo "Hello Step 3!"' + step4: + image: node + stage: 'build' + commands: + - 'echo "Hello Step 4!"' + step5: + image: node + stage: 'scan' + commands: + - 'echo "Hello Step 5!"' + step6: + image: node + stage: 'scan' + commands: + - 'echo "Hello Step 6!"' + step7: + image: node + stage: 'integration' + commands: + - 'echo "Hello Step 7!"' + step8: + image: node + stage: 'deploy' + commands: + - 'echo "Hello Step 8!"' + step9: + image: node + stage: 'deploy' + commands: + - 'echo "Hello Step 9!"' +{% endraw %} +{% endhighlight %} + +If you run the pipeline you will see this view + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/complex.png" +url="/images/codefresh-yaml/stages/complex.png" +alt="Complex Pipeline view" +caption="Complex Pipeline view" +max-width="80%" +%} + +Remember that the assignment of a step to a stage is happening only for graphical grouping purposes. It does +not affect the way your steps run. All steps will still run in the same order mentioned in the `codefresh.yml` file. + +Also notice if you enable this view a stage called *default* will show all build steps that are not explicitly assigned to a stage. + +## Using spaces in stage names + +If you wish to have spaces in stage names you need to quote them like this: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- 'my build phase' +- 'my test phase' +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'my build phase' + type: build + image_name: my-app + dockerfile: Dockerfile + MyUnitTests: + title: Unit testing + stage: 'my test phase' + image: ${{MyAppDockerImage}} + commands: + - npm run test +{% endraw %} +{% endhighlight %} + + +## What to read next + +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Parallel workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) diff --git a/_docs/pipelines/steps.md b/_docs/pipelines/steps.md new file mode 100644 index 00000000..6cdfb52e --- /dev/null +++ b/_docs/pipelines/steps.md @@ -0,0 +1,1223 @@ +--- +title: "Steps" +description: "Learn the types of Pipeline steps" +group: codefresh-yaml +redirect_from: + - /docs/steps/ +toc: true +--- + +Codefresh [pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) are composed of a series of steps. + +You can create your own pipelines by writing a [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file that describes your pipeline. This file can then be version controlled on its own (pipeline as code). + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/stages/complex-pipeline.png" +url="/images/codefresh-yaml/stages/complex-pipeline.png" +alt="Pipeline steps" +caption="Pipeline steps" +max-width="80%" +%} + +## Built-in steps + +The steps offered by Codefresh are: + +* [Git clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +* [Freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +* [Build]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +* [Push]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) +* [Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) +* [Launch test environment]({{site.baseurl}}/docs/codefresh-yaml/steps/launch-composition/) +* [Deploy]({{site.baseurl}}/docs/codefresh-yaml/steps/deploy/) +* [Approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) + +**Git clone** steps allow you to checkout code in your pipeline from any internal or external repository. Existing accounts that still use repositories instead of [projects]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-concepts) have an implicit clone step in the pipelines. + +**Freestyle** steps are the cornerstone of Codefresh pipelines. They allow you to run any command within the context of a Docker container. A lot of Codefresh optimizations such as the [shared docker volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are designed specifically for freestyle steps. +Freestyle steps are a secure replacement for `docker run` commands. + +**Build** steps are the main way where you get access to the Docker daemon (Docker as a service) in Codefresh pipelines. Build steps take as input any Dockerfile and run it on the cloud in a similar manner to what you do on your workstation. Build steps automatically push the result to the default Docker registry of your account (no need for docker login commands). Codefresh also comes with a global Docker cache that automatically gets attached to all build nodes. Build steps are a secure replacement for `docker build` commands. + +**Push** steps allow you to push and tag your docker images (created by the build step) in any [external Docker registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). Push steps are *not* needed at all if you work with only the internal Codefresh registry. Push steps are a secure replacement for the `docker tag` and `docker push` commands. + +**Composition** steps allow you to run multiple services together in the Codefresh infrastructure and execute unit tests or other commands against them. They are discarded once a pipeline finishes. Composition steps are a secure replacement for `docker-compose` definitions. + +**Launch test environment** steps behave similar to compositions, but they persist after the pipeline ends. This is a great way to create preview environment from your pull requests and send to colleagues. + +**Deploy steps** allow you to [perform Kubernetes deployments]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes/) in a declarative manner. They embody the Continuous Deployment aspect of Codefresh. + +**Approval steps** allow you to pause pipelines and wait for human intervention before resuming. They allow you to embrace the concepts of Continuous Delivery. + +>Note that Codefresh also supports [parallel workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) as well as running pipelines [locally on your workstation]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/). + +## Step directory + +In the case of freestyle steps we also offer a [plugin marketplace](https://codefresh.io/steps/) with several existing plugins for popular integrations. + +{% include +image.html +lightbox="true" +file="/images/pipeline/plugin-directory.png" +url="/images/pipeline/plugin-directory.png" +alt="Codefresh steps directory" +caption="Codefresh steps directory" +max-width="80%" +%} + +Codefresh steps can be: + +* Private (visible only to you and your team) or public (visible to everybody via the marketplace) +* Official (supported by the Codefresh team) or community based +* Ready for production or still incubating. + +You can use any your pipelines any of the public steps already in the marketplace, any steps created by your team and any steps that you create for yourself. + +## Using custom pipeline steps + +When you create a pipeline, you will have access to two categories of steps: + +* Public steps that exist in the marketplace +* Steps that you or your team have created (visible only to you) + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/choose-step.png" +url="/images/codefresh-yaml/steps/choose-step.png" +alt="Choosing a custom step" +caption="Choosing a custom step" +max-width="60%" +%} + +To use a step, first click on the pipeline section where you want to insert the step. +You will get a new dialog with all the details of the step along with a live preview of the exact +[yaml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) that will be inserted in your pipeline. + +For all steps you can define: + +* The title of the text (which will also be visible in the pipeline UI) +* A freetext description +* The [stage]({{site.baseurl}}/docs/codefresh-yaml/stages/) that will contain the step + +The rest of the fields are specific to each step. See the documentation of each step in order to understand what each field should contain. There are fields for each step that are marked as required and are essential for the step to work. These are marked with an asterisk. + +Once a step is added to the pipeline, you are fee to change the resulting yaml even further by just typing in the pipeline editor. + +## Creating your own step + +There are two ways to create custom steps in Codefresh. The simplest way is to package an existing CLI tool into a Docker image and use it as a freestyle step. The more advanced way is creating a typed step with explicit input and output parameters. + +Here is a summary on the two ways: + +{: .table .table-bordered .table-hover} +| | Custom freestyle step | Codefresh typed plugin | +| -------------- | ---------------------------- |-------------------------| +| Assets needed | A Docker image | A Docker image and a plugin manifest| +| Knowledge required | Docker building/pushing | Docker and Codefresh CLI | +| Step can be used | In any Docker based CI/CD platform | In Codefresh | +| Effort required | Minimal | Medium | +| Distribution via | Dockerhub | Codefresh marketplace | +| Input variables | Yes | Yes| +| Output variables | No | Yes | +| Versioning via | Docker tags | Manifest entry | +| Grouping of multiple steps | No | Yes | +| Marketplace entry | Not possible| Possible/optional | +| Best for sharing steps | with your team/company | with the world | + + + +We suggest that you start with custom freestyle steps first and only create typed plugins once you are familiar with Codefresh pipelines or want your plugin to appear in the marketplace. + + +### Creating a custom freestyle step + +As an example let's say that you need to use the [JFrog CLI](https://jfrog.com/getcli/) in a pipeline in order to interact with a Artifactory or Bintray. JFrog does not offer any Docker image that contains the CLI and you already know that all Codefresh steps [are actually Docker images]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). + +Therefore you can easily package the CLI into a Docker image and then make it available to any Codefresh pipeline that wishes to use it. +First you create [a Dockerfile](https://github.com/kostis-codefresh/step-examples/blob/master/jfrog-cli-wrapper/Dockerfile) that packages the CLI + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM debian:stable-slim + +WORKDIR /jfrog-cli + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* + +RUN curl -fL https://getcli.jfrog.io | sh + +ENV JFROG_CLI_OFFER_CONFIG false +ENV BINTRAY_LICENCES MIT + +RUN /jfrog-cli/jfrog bt config --licenses $BINTRAY_LICENCES + +RUN ln -s /jfrog-cli/jfrog /usr/local/bin/jfrog + +CMD ["/jfrog-cli/jfrog"] +{% endraw %} +{% endhighlight %} + +This is a standard Dockerfile. There is nothing specific to Codefresh in the image that gets created. You can test this Dockerfile locally with + +{% highlight shell %} +{% raw %} +docker build . -t jfrog-cli +docker run jfrog-cli +{% endraw %} +{% endhighlight %} + +In a similar manner you can package any other executable and its dependencies. You could even just package `curl` with an external URL that hosts the service that you want to interact in a Codefresh pipeline. + +Once the Dockerfile is ready, you need to push it to Dockerhub. You can either do it manually from your workstation, but it is best if you actually create a [Codefresh pipeline](https://github.com/kostis-codefresh/step-examples/blob/master/jfrog-cli-wrapper/codefresh.yml) that does it for you. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/create-custom-step.png" +url="/images/codefresh-yaml/steps/create-custom-step.png" +alt="Creating a custom freestyle step" +caption="Creating a custom freestyle step" +max-width="80%" +%} + +Now that the image is ready and public you can notify your team that the new plugin is ready. +Everybody who wants to interact with JFrog Bintray and/or Artifactory can place [the following snippet](https://github.com/kostis-codefresh/step-examples/blob/master/jfrog-cli-wrapper/codefresh-example.yml) in a pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + run_frog_cli: + title: Running jfrog CLI inside Docker + image: kkapelon/jfrog-cli + commands: + - jfrog bt --help + - jfrog rt --help +{% endraw %} +{% endhighlight %} + +You can then customize the exact command(s) that you want to run with the tool. All capabilities of freestyle steps are possible, such as passing environment variables as input parameters. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + run_frog_cli: + title: Running jfrog CLI inside Docker + image: kkapelon/jfrog-cli + commands: + - jfrog bt package-show google/tensorflow/tensorflow + environment: + - BINTRAY_USER=my-user + - BINTRAY_KEY=my-secret-key +{% endraw %} +{% endhighlight %} + +If you want to use multiple versions of the step in the same pipeline, you can just create different docker tags. Notice that you can also use a [private registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) instead of Dockerhub if you wish your step to be used only within your organization. + + + +### Creating a typed Codefresh plugin + +You can use the [Codefresh CLI](https://codefresh-io.github.io/cli/) and more specifically the [step-type resource](https://codefresh-io.github.io/cli/steps/) to create your own typed step. Each Codefresh step is composed from two parts: + +1. The step description in the special yaml syntax for describing Codefresh steps +1. A Docker image that implements the step (optional) + +The easiest way to create your own step is to start by using the definition of an existing step. + +{% highlight bash %} +codefresh get step-type vault -o yaml > vault-step.yml +{% endhighlight %} + +Here is the resulting yaml: + + `vault-step.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: / + isPublic: false + description: >- + The plugin exports KV pairs from Hashicorp Vault to Codefresh pipeline ENV + variables + sources: + - 'https://github.com/codefresh-io/steps/tree/master/incubating/vault' + stage: incubating + maintainers: + - name: Alexander Aladov + categories: + - featured + official: false + tags: [] + icon: + type: svg + url: 'https://cdn.jsdelivr.net/gh/codefresh-io/steps/incubating/vault/icon.svg' + background: '#f4f4f4' + examples: + - description: example-1 + workflow: + version: '1.0' + steps: + Vault_to_Env: + title: Importing vault values + type: vault + arguments: + VAULT_ADDR: '${{VAULT_ADDR}}' + VAULT_PATH: '${{VAULT_PATH}}' + VAULT_AUTH_TOKEN: '${{VAULT_AUTH_TOKEN}}' + VAULT_CLIENT_CERT_BASE64: '${{VAULT_CLIENT_CERT_BASE64}}' + VAULT_CLIENT_KEY_BASE64: '${{VAULT_CLIENT_KEY_BASE64}}' + created_at: '2019-07-03T14:57:02.057Z' + updated_at: '2019-09-18T08:15:28.476Z' + latest: true + version: 0.0.1 + id: 5d1cc23ea7e22e40227ea75d +spec: + arguments: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "patterns": [], + "required": [ + "VAULT_ADDR", + "VAULT_PATH", + "VAULT_AUTH_TOKEN" + ], + "properties": { + "VAULT_ADDR": { + "type": "string", + "description": "Vault server URI. Example: https://vault.testdomain.io:8200 (required)" + }, + "VAULT_PATH": { + "type": "string", + "description": "Path to secrets in vault. Example: secret/codefreshsecret (required)" + }, + "VAULT_AUTH_TOKEN": { + "type": "string", + "description": "Vault authentication token (required)" + }, + "VAULT_CLIENT_CERT_BASE64": { + "type": "string", + "description": "Base64 encoded client cerificate" + }, + "VAULT_CLIENT_KEY_BASE64": { + "type": "string", + "description": "Base64 encoded client key" + } + } + } + steps: + main: + name: vault + image: codefreshplugins/vault + environment: + - 'VAULT_ADDR=${{VAULT_ADDR}}' + - 'VAULT_PATH=${{VAULT_PATH}}' + - 'VAULT_AUTH_TOKEN=${{VAULT_AUTH_TOKEN}}' + - 'VAULT_CLIENT_CERT_BASE64=${{VAULT_CLIENT_CERT_BASE64}}' + - 'VAULT_CLIENT_KEY_BASE64=${{VAULT_CLIENT_KEY_BASE64}}' +{% endraw %} +{% endhighlight %} + +For each step you define the following sections: + +* Metadata to describe the characteristics of the step +* The description of its arguments +* The implementation (i.e. what yaml gets inserted in the pipeline) + +For the metadata section note the following: + +* `isPublic` decides if this step is visible only to your and your team, or visible to all (in the marketplace) +* The `name` of the step **must** be prefixed with your Codefresh account name. Steps created by the Codefresh team are on the root level of the hierarchy (without prefix). This is the same pattern that Dockerhub is using for images. +* `stage` shown if this step is ready for production or still incubating. This is just an indication to users. It doesn't affect the implementation of the step in any way +* `icon`. Ideally you provide a transparent svg so that the icon is scalable. The icon for a step is used both in the marketplace as well as the pipeline view. You can also select a default background to be used. Alternatively, you can define jpg/png icons for large/medium/small sizes. We suggest the svg approach +* The `version` property allows you to update your plugin and keep multiple variants of it in the marketplace +* The `examples` section will be shown in the marketplace as documentation for your step + +For the argument section we follow the [JSON Schema](http://json-schema.org/learn/miscellaneous-examples.html). You can use the [Schema generator](https://jsonschema.net/) to easily create a schema. JSON schema is used for arguments (i.e. input parameters) as well as output parameters as we will see later on. + +The property `additionalProperties` defines how strict the plugin will be with its arguments. If you set it to `false` (which is usually what you want) the pipeline will fail if the plugin is given more arguments that it is expecting. If you set it to `true`, then the plugin will only use the arguments it understands and will ignore the rest. + +The final part is the step implementation. Here you can define exactly the yaml that this step will insert in the pipeline. You can use any of the built-in steps in Codefresh and even add multiple steps. + +>Note that currently you cannot nest custom pipeline steps. We are aware of this limitation and are actively working on it, but at the time or writing you cannot use a typed step inside another typed step. + +Once you are done with your step, use the Codefresh CLI to upload it to the marketplace. If you want the step to be available only to you and your team make sure that the property `isPublic` is false (and then it will not be shown in the marketplace). + +{% highlight bash %} +codefresh create step-type -f my-custom-step.yml +{% endhighlight %} + +If you make further changes to your step you can update it: + +{% highlight bash %} +codefresh replace step-type -f my-custom-step.yml +{% endhighlight %} + +If you want to remove your step from the marketplace, you can delete it completely: + +{% highlight bash %} +codefresh delete step-type kostis-codefresh/sample +{% endhighlight %} + +### Versioning of typed steps + +The `version` property under `metadata` in the plugin manifest allows you to publish multiple releases of the same plugin in the marketplace. Codefresh will keep all previous plugins and users are free to choose which version they want. + +To create a new version of your plugin: + +1. Update the `version` property under `metadata` in your custom YAML. +2. Run: + +{% highlight bash %} +codefresh create step-type -f custom-plugin.yaml +{% endhighlight %} + +You will now be able to see the new versions of your plugin in the step marketplace drop-down: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/step-versions.png" +url="/images/codefresh-yaml/steps/step-versions.png" +alt="Different step versions" +caption="Different step versions" +max-width="60%" +%} + +You can also use the Codefresh CLI to list all version: + +{% highlight bash %} +codefresh get step-types kostis-codefresh/sample --versions +{% endhighlight %} + +To delete a specific version, use: + +{% highlight bash %} +codefresh delete step-type 'account/plugin:' +{% endhighlight %} + +Note that Codefresh step versions function like Docker tags in the sense that they are *mutable*. You can overwrite an existing plugin version with a new plugin manifest by using the `codefresh replace step-type` command. + +If users do not define a version once they use the plugin, the latest one (according to [semantic versioning](https://semver.org/)) will be used. Alternatively they can specify the exact version they need (even different versions within the same pipeline.) + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_step_1: + title: Running old custom step + type: kostis-codefresh/sample:1.2.1 + my_step_2: + title: Running new custom step + type: kostis-codefresh/sample:1.3.5 +{% endraw %} +{% endhighlight %} + +### Example with input parameters + +Let's create a very simple step called *node-version*. This step will read the application version from a NodeJS project and expose it as an environment variable. This way we can use the application version later in the pipeline (for example to tag a docker image). + +Here is the respective [step yaml](https://github.com/kostis-codefresh/step-examples/blob/master/node-version-plugin/read-app-version.yml). + + `plugin.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: kostis-codefresh/node-version + isPublic: false + description: >- + The plugin exports as an environment variable the application version from package.json + sources: + - 'https://github.com/kostis-codefresh/step-examples' + stage: incubating + maintainers: + - name: Kostis Kapelonis + categories: + - utility + official: false + tags: [] + icon: + type: svg + url: https://cdn.worldvectorlogo.com/logos/nodejs-icon.svg + background: '#f4f4f4' + examples: + - description: example-1 + workflow: + version: '1.0' + steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'my-github-user/my-github-repo' + revision: 'master' + git: github + read_app_version: + title: Reading app version + type: kostis-codefresh/node-version + arguments: + PACKAGE_JSON_FOLDER: './my-github-repo' + print_app_version: + title: Printing app version + image: alpine + commands: + - echo $APP_VERSION + latest: true + version: 1.0.0 +spec: + arguments: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "patterns": [], + "required": [ + "PACKAGE_JSON_FOLDER" + ], + "properties": { + "PACKAGE_JSON_FOLDER": { + "type": "string", + "description": "folder where package.json is located" + } + } + } + steps: + main: + name: kostis-codefresh/node-version + image: node + commands: + - cd $WORK_DIR + - pwd + - APP_VERSION=$(node -p -e "require('./package.json').version") + - echo $APP_VERSION + - export APP_VERSION + - cf_export APP_VERSION + environment: + - 'WORK_DIR=${{PACKAGE_JSON_FOLDER}}' +{% endraw %} +{% endhighlight %} + +If you look at the `spec` section you will see that the plugin expects a single parameter called `PACKAGE_JSON_FOLDER`. This will +be passed by the plugin user to specify the folder that contains the `package.json` file. This way this plugin can be used for multiple applications. For example, the plugin user might check out 3 different Node.js projects and use the plugin to read the versions of all of them. + +The plugin implementation is specified in the `steps` sections. We use the standard [Node Docker image](https://hub.docker.com/_/node) to read the version from the `package.json` file. Notice how we convert the plugin argument to an environment variable called `WORK_DIR` + +By default all plugins start with the Codefresh volume at `/codefresh/volume` as a working folder. So with the `cd` command we enter the project folder (which we assume was checked out in a previous pipeline step). Once the version is read it is made available to all the other pipeline steps with the [cf_export command]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command). + +We now insert our plugin in the marketplace with the following command: + +{% highlight bash %} +codefresh create step-type -f read-app-version.yml +{% endhighlight %} + +The step is now ready to be used by anybody. + +An example user pipeline is shown at [codefresh.yml](https://github.com/kostis-codefresh/step-examples/blob/master/node-version-plugin/codefresh.yml) + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/example_nodejs_postgres' + revision: 'master' + git: github + read_app_version: + title: Reading app version + type: kostis-codefresh/node-version + arguments: + PACKAGE_JSON_FOLDER: './example_nodejs_postgres' + print_app_version: + title: Printing app version + image: alpine + commands: + - echo $APP_VERSION +{% endraw %} +{% endhighlight %} + +This is a very simple pipeline that checks out a NodeJS project and uses our plugin. Notice how we pass as argument the required parameter `example_nodejs_postgres` to tell the plugin where our `package.json` file is located. Once the plugin runs the application version is available as an environment variable that we can use in other steps as `APP_VERSION`. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/input-parameters.png" +url="/images/codefresh-yaml/steps/input-parameters.png" +alt="Step input parameters" +caption="Step input parameters" +max-width="60%" +%} + +The input parameter is also shown as required in the marketplace. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/input-parameters-definition.png" +url="/images/codefresh-yaml/steps/input-parameters-definition.png" +alt="Input parameters on marketplace" +caption="Input parameters on marketplace" +max-width="40%" +%} + +This is a trivial example, but is still shows how Codefresh pipeline can be declarative while actually doing a lot of imperative actions behind the scenes. + +### Example with output parameters + +In the previous example our plugin had an output parameter (`APP_VERSION`) that is created by the custom step and given back to the user. Even though creating an output parameter using only `cf_export` will work just fine in the technical level, it is best to formally define output parameters in the step definition. + +If you define output parameters in the step definition their names will appear on the marketplace and users will have an easier time understand what your step produces. You will be able to define complete JSON objects in addition to output strings. Formal output parameters are also available under a special notation (`step.outputs`) that we will explain in this example. + +We suggest you always formalize your output parameters in your step definition, especially when your step is having a large number of output parameters. + +The same [JSON Schema](http://json-schema.org/learn/miscellaneous-examples.html) is also used for output parameters as with input ones. +Here is a [very simple example](https://github.com/kostis-codefresh/step-examples/blob/master/output-parameters/output-parameters-sample.yml) that shows the different types of output parameters you can have. + + `plugin.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: kostis-codefresh/output-parameters-example + isPublic: false + description: >- + The plugin shows how you can export output parameters + sources: + - 'https://github.com/kostis-codefresh/step-examples' + stage: incubating + maintainers: + - name: Kostis Kapelonis + categories: + - utility + official: false + tags: [] + icon: + type: svg + url: https://cdn.worldvectorlogo.com/logos/bash-1.svg + background: '#f4f4f4' + examples: + - description: example-1 + workflow: + version: '1.0' + steps: + dummy_parameters: + title: Creating output parameters + type: kostis-codefresh/output-parameters-example + print_my_variables: + title: Printing dummy content + image: alpine + commands: + - echo $MY_NUMBER + - echo $MY_CITY + - echo $MY_FAVORITE_FOOD + - echo ${{steps.dummy_parameters.output.MY_NUMBER}} + - echo ${{steps.dummy_parameters.output.MY_CITY}} + - echo ${{steps.dummy_parameters.output.MY_FAVORITE_FOOD}} + latest: true + version: 1.0.0 +spec: + returns: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "patterns": [], + "required": [ + "MY_NUMBER", + "MY_CITY", + "MY_FAVORITE_FOOD" + ] + , + "properties": { + "MY_NUMBER": { + "type": "number", + "description": "an example variable that holds a number" + }, + "MY_CITY": { + "type": "object", + "description": "an example variable that holds a JSON object", + "required": ["city_name", "country", "population"], + "properties": { + "city_name": {"type": "string"}, + "country": {"type": "string"}, + "population": {"type": "integer"} + } + }, + "MY_FAVORITE_FOOD": { + "description": "an example variable that holds a number", + "type": "array", + "maxItems": 3, + "items": { + "type": "string" + } + } + } + } + steps: + main: + name: kostis-codefresh/output-parameters-example + image: alpine + commands: + - cf_export MY_NUMBER=42 + - cf_export MY_CITY='{"city_name":"San Francisco", "country":"usa","population":884363}' + - cf_export MY_FAVORITE_FOOD='["pizza", "ramen", "hot dogs"]' + +{% endraw %} +{% endhighlight %} + +This plugin exports 3 output parameters + +* `MY_NUMBER` - a single number +* `MY_CITY` - an object with fields `city_name`, `country`, `population` +* `MY_FAVORITE_FOOD` - an array. + +Output parameters are defined in the `returns` block. +The output parameters of the step are now shown in the marketplace so consumers of this plugin know what to expect when they use it. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/output-parameters-definition.png" +url="/images/codefresh-yaml/steps/output-parameters-definition.png" +alt="Output parameters on marketplace" +caption="Output parameters on marketplace" +max-width="40%" +%} + +As can be seen from the `examples` block, when you have formal output parameters you can also access them by mentioning the specific steps in your pipeline that creates it. The following are two equal ways to use an output parameter in your pipeline: + +``` +{% raw %} +echo $MY_NUMBER +echo ${{steps.dummy_parameters.output.MY_NUMBER}} +{% endraw %} +``` + +In the case of output parameters that are objects you can also use `jq` to get specific properties like this: + +``` +{% raw %} +echo ${{steps.dummy_parameters.output.MY_CITY}} | jq '.city_name' +{% endraw %} +``` + +This will print "San Francisco". + + +### Example with input/output parameters + +Let's take everything we learned from the previous examples and create a custom step that has + +1. A custom Docker image +1. Formal input parameters +1. Format output parameters + +In this simple example we will create a custom step that reads the Maven coordinates from a `pom.xml` file. Unlike `package.json`, a Maven file has 3 characteristics (group, artifact name and version). First we create a [very simple executable](https://github.com/kostis-codefresh/step-examples/blob/master/maven-version-plugin/mvncoords.go) that reads a Maven file and gives us these coordinates in JSON format. + +{% highlight shell %} +{% raw %} +mvncoords -f pom.xml +{"groupId":"com.example.codefresh","artifactId":"my-java-app","version":"3.0.2"} +{% endraw %} +{% endhighlight %} + +Next, we package this executable in a [Dockerfile](https://github.com/kostis-codefresh/step-examples/blob/master/maven-version-plugin/Dockerfile). + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.12-alpine AS build_base + +WORKDIR /tmp/ + +COPY . . + +# Unit tests +RUN go test -v + +# Build the Go app +RUN go build -o ./out/mvncoords . + +# Start fresh from a smaller image +FROM alpine:3.9 + +COPY --from=build_base /tmp/out/mvncoords /usr/local/bin/mvncoords + +CMD ["mvncoords"] +{% endraw %} +{% endhighlight %} + +We now have a custom Docker image that contains our executable. If we want other people to use it, we need to push it to Dockerhub. You can do this manually from your workstation using `docker login` and `docker push` commands, but it is much better to automate this with a Codefresh pipeline. + + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/create-plugin-image.png" +url="/images/codefresh-yaml/steps/create-plugin-image.png" +alt="Building a public Docker image" +caption="Building a public Docker image" +max-width="60%" +%} + +This [pipeline](https://github.com/kostis-codefresh/step-examples/blob/master/maven-version-plugin/codefresh.yml) checks out the Dockerfile plus source code, builds the docker image and then pushes it to Dockerhub (so that the image is public). + +Finally we are ready to create our Codefresh plugin. Here is the [specification](https://github.com/kostis-codefresh/step-examples/blob/master/maven-version-plugin/read-maven-version.yml): + + + + `plugin.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: kostis-codefresh/mvn-version + isPublic: false + description: >- + The plugin exports as an environment variable the mvn coordinates from pom.xml + sources: + - 'https://github.com/kostis-codefresh/step-examples' + stage: incubating + maintainers: + - name: Kostis Kapelonis + categories: + - utility + official: false + tags: [] + icon: + type: svg + url: https://cdn.worldvectorlogo.com/logos/java-4.svg + background: '#f4f4f4' + examples: + - description: example-1 + workflow: + version: '1.0' + steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'my-github-user/my-github-repo' + revision: 'master' + git: github + read_app_version: + title: Reading app version + type: kostis-codefresh/mvn-version + arguments: + POM_XML_FOLDER: './my-github-repo' + print_app_version: + title: Printing app coordinates + image: alpine + commands: + - echo $MVN_COORDS + - echo ${{steps.read_app_version.output.MVN_COORDS}} + latest: true + version: 1.0.0 +spec: + arguments: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "patterns": [], + "required": [ + "POM_XML_FOLDER" + ], + "properties": { + "POM_XML_FOLDER": { + "type": "string", + "description": "folder where pom.xml is located" + } + } + } + returns: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "patterns": [], + "required": [ + "MVN_COORDS" + ], + "properties": { + "MVN_COORDS": { + "type": "object", + "required": ["groupId", "artifactId", "version"], + "properties": { + "groupId": {"type": "string"}, + "artifactId": {"type": "string"}, + "version": {"type": "string"} + } + } + } + } + steps: + main: + name: kostis-codefresh/mvn-version + image: kkapelon/maven-version-extract + commands: + - cd $WORK_DIR + - MVN_COORDS=$(mvncoords -json) + - export MVN_COORDS + - cf_export MVN_COORDS + environment: + - 'WORK_DIR=${{POM_XML_FOLDER}}' +{% endraw %} +{% endhighlight %} + +We place this plugin into the marketplace with + +``` +codefresh create step-type -f read-maven-version.yml +``` + +If you look at the plugin entry in the marketplace you will see both input (the folder of the pom.xml) and output parameters (mvn coordinates) defined: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/plugin-parameters.png" +url="/images/codefresh-yaml/steps/plugin-parameters.png" +alt="Input and output parameters" +caption="Input and output parameters" +max-width="60%" +%} + +The plugin is now ready to be used in a pipeline: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/plugin-usage.png" +url="/images/codefresh-yaml/steps/plugin-usage.png" +alt="Plugin usage" +caption="Plugin usage" +max-width="60%" +%} + +If you look at the [pipeline definition](https://github.com/kostis-codefresh/step-examples/blob/master/maven-version-plugin/codefresh-example.yml) you will see how we pass arguments in the plugin and get its output with the `steps.output` syntax. + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/spring-boot-2-sample-app' + revision: 'master' + git: github + read_app_version: + title: Reading app version + type: kostis-codefresh/mvn-version + arguments: + POM_XML_FOLDER: './spring-boot-2-sample-app' + print_app_version: + title: Printing app version + image: alpine + commands: + - echo $MVN_COORDS + - echo ${{steps.read_app_version.output.MVN_COORDS}} +{% endraw %} +{% endhighlight %} + +This was a trivial example, but it clearly demonstrates how a custom step communicates with the rest of the pipeline by getting input from the previous steps and preparing output for the steps that follow it. + +### Exporting parameters manually inside a plugin + +Normally, in a pipeline you can either use the [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) command or write directly to the [/codefresh/volume/env_vars_to_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#directly-writing-to-the-file) file. + +However, inside a plugin you can also use the `/meta/env_vars_to_export` file that has the same semantics, but is used for exporting variables in the same scope as the plugin only. + +The rules for using `/meta/env_vars_to_export` are: +- When the step-type (plugin) does not define the `return` schema, all the output variables from substeps will be projected and exported as the root step (they may override each other). +- When `return` schema is defined, only the variables that matched the definition will be exported as root step. + +`plugin.yaml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: /my-step + ... +spec: + arguments: |- + { + ... + } + returns: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "patterns": [], + "required": [ + "ROOT_VAR" + ] + , + "properties": { + "ROOT_VAR": { + "type": "string", + "description": "an example variable" + } + } + } + steps: + export_my_variable: + title: "Exporting custom variable" + image: alpine + commands: + - echo PLUGIN_VAR=Alice >> /meta/env_vars_to_export + - echo ROOT_VAR=Bob >> /meta/env_vars_to_export + read_my_variable: + title: "Reading custom variable" + image: alpine + commands: + - source /meta/env_vars_to_export + - echo $PLUGIN_VAR #Alice + - echo $ROOT_VAR #Bob +{% endraw %} +{% endhighlight %} + + +`codefresh.yaml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + plugin: + type: /my-step + echo: + image: alpine + commands: + - echo $PLUGIN_VAR #empty + - echo $ROOT_VAR #Bob +{% endraw %} +{% endhighlight %} + +You can still use `cf_export` command inside the plugin as well (as shown in the previous examples). + + +### Example with step templating + +As an advanced technique, Codefresh allows you to define a custom step using templating instead of fixed YAML. We support templates inside the `spec:` block of a plugin definition by taking advantage of the [Gomplate](https://github.com/hairyhenderson/gomplate) library that offers additional templating functions on top of vanilla [Go templates](https://golang.org/pkg/text/template/). + +> Note: Gomplate Data functions will not work since Codefresh does not pass the Data object to gomplate functions. + +As a simple example lets say we want to create a single step that checks out any number of git repositories. Of course you could just copy-paste the git clone step multiple times in a single pipeline. To make things easier we will create a single step that takes an array of git repositories and checks them out on its own: + +{% highlight yaml %} +{% raw %} +checkout_many_projects: + title: Checking out my Git projects + type: kostis-codefresh/multi-git-clone + arguments: + GIT_PROJECTS: + - 'codefresh-contrib/ruby-on-rails-sample-app' + - 'kubernetes/sample-apiserver' + - 'kostis-codefresh/nestjs-example' + - 'spring-projects/spring-petclinic' +{% endraw %} +{% endhighlight %} + +The GitHub projects are passed as an array, so if we want to check out an additional project, we simply add items to that array. + +Here is the [step specification](https://github.com/kostis-codefresh/step-examples/blob/master/multi-clone/multi-clone-step.yml): + + `plugin.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +kind: step-type +metadata: + name: kostis-codefresh/multi-git-clone + isPublic: false + description: >- + This pipeline plugin shows templating of custom steps + sources: + - 'https://github.com/kostis-codefresh/step-examples' + stage: incubating + maintainers: + - name: Kostis Kapelonis + categories: + - git + official: false + tags: [] + icon: + type: svg + url: https://cdn.worldvectorlogo.com/logos/git.svg + background: '#f4f4f4' + examples: + - description: example-1 + workflow: + version: '1.0' + steps: + checkout_many_projects: + title: Checking out my Git projects + type: kostis-codefresh/multi-git-clone + arguments: + GIT_REVISION: 'master' + GIT_PROVIDER: 'github' + GIT_PROJECTS: + - 'codefresh-contrib/ruby-on-rails-sample-app' + - 'kubernetes/sample-apiserver' + - 'kostis-codefresh/nestjs-example' + - 'spring-projects/spring-petclinic' + latest: true + version: 1.0.0 +spec: + arguments: |- + { + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "patterns": [], + "required": [ + "GIT_PROJECTS", + "GIT_REVISION", + "GIT_PROVIDER" + ], + "properties": { + "GIT_REVISION": { + "type": "string", + "description": "branch or tag or revision to checkout (same for all projects)" + }, + "GIT_PROVIDER": { + "type": "string", + "description": "Name of git provider to use from Codefresh integrations screen" + }, + "GIT_PROJECTS": { + "description": "A list/array of git projects to checkout", + "type": "array", + "maxItems": 10, + "items": { + "type": "string" + } + } + } + } + delimiters: + left: '[[' + right: ']]' + stepsTemplate: |- + print_info_message: + name: kostis-codefresh/multi-git-clone + title: Info message + image: alpine + commands: + - echo "Checking out [[ len .Arguments.GIT_PROJECTS ]] git projects" + [[ range $index, $git_project :=.Arguments.GIT_PROJECTS ]] + clone_project_[[$index]]: + title: Cloning [[$git_project]] ... + type: git-clone + repo: '[[$git_project]]' + revision: [[$.Arguments.GIT_REVISION]] + git: [[$.Arguments.GIT_PROVIDER]] + [[end]] +{% endraw %} +{% endhighlight %} + +There are two important points here: + +1. Instead of using a `steps:` block, we instead define a block called `stepsTemplate:`. This block name instructs Codefresh that we will use templates +1. Because the Codefresh runtime is already using the double curly braces for variables mentioned as {% raw %}`${{MY_VARIABLE_EXAMPLE}}`{% endraw %}, we instead define templates with the characters {% raw %}`[[]]`{% endraw %}. You can see the definitions for these characters inside the `delimiters:` block. You are free to use any other replacement characters of your choosing. + +In the `stepsTemplate` block we use Golang template keywoards such as `range`, `len` and template variables (such as `git_project`). You can use all the capabilities of Go templates (e.g. `if`, `range`, `with`) as well as the extra methods of [gomplate](https://docs.gomplate.ca/) such as math and net functions. + +Creating the [marketplace entry](https://codefresh.io/steps/step/kostis-codefresh%2Fmulti-git-clone) for a step with templates is exactly the same as any other step: + +``` +codefresh create step-type -f multi-clone-step.yml +``` + +You can then use the step in [any pipeline](https://github.com/kostis-codefresh/step-examples/blob/master/multi-clone/codefresh.yml) and pass the arguments that will fill the template: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + checkout_many_projects: + title: Checking out my Git projects + type: kostis-codefresh/multi-git-clone + arguments: + GIT_REVISION: 'master' + GIT_PROVIDER: 'github' + GIT_PROJECTS: + - 'codefresh-contrib/ruby-on-rails-sample-app' + - 'kubernetes/sample-apiserver' + - 'kostis-codefresh/nestjs-example' + - 'spring-projects/spring-petclinic' + print_my_workspace: + title: Show projects + image: alpine + commands: + - ls -l + - pwd +{% endraw %} +{% endhighlight %} + +We have also added two extra parameters, one for the git revision and one for the [git provider]({{site.baseurl}}/docs/integrations/git-providers/) that will be used during checkout. + +The end result is that with a single step you can checkout many projects. Checking out an additional project is as simple as adding a new entry in the `GIT_PROJECTS` array. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/multi-checkout.png" +url="/images/codefresh-yaml/steps/multi-checkout.png" +alt="Checking out multiple Git repositories in a single step" +caption="Checking out multiple Git repositories in a single step" +max-width="60%" +%} + +This was a contrived example to demonstrate how you can use templates in the Codefresh plugin specification. Note that using templates in Codefresh steps is an advanced technique and should be used sparingly. + +### Limitations of custom plugins + +[Parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) are not supported inside custom steps. + +Within a custom step, the [fail_fast field]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#execution-flow) does not work. Use the `failFast` field instead. + +Custom steps are not compatible with [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/). +More specifically: + + * If you have a [service container in the pipeline-level]({{site.baseurl}}/docs/codefresh-yaml/service-containers/#running-services-for-the-duration-of-the-pipeline), steps inside the custom plugin will not be able to access it + * If you try to attach a service container to a custom plugin, the plugin will fail when executed + * If you try to define a custom plugin where a step inside it has a service container attached, the custom plugin will fail when executed + +## What to read next + +* [Introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) +* [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +* [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +* [Push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) diff --git a/_docs/pipelines/steps/approval.md b/_docs/pipelines/steps/approval.md new file mode 100644 index 00000000..1d528656 --- /dev/null +++ b/_docs/pipelines/steps/approval.md @@ -0,0 +1,350 @@ +--- +title: "Approval" +description: "How to Pause Pipelines for Manual Approval" +group: codefresh-yaml +sub_group: steps +toc: true +--- + +The approval step allows you to pause a pipeline and wait for human intervention before going on. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/approval-waiting.png" +url="/images/codefresh-yaml/approval/approval-waiting.png" +alt="Manual Approval step" +caption="Manual Approval step" +max-width="80%" +%} + +Some example scenarios for using the approval step: + +* Pause before deploying to production +* Pause before destroying an environment +* Pause for some manual smoke tests or metric collection + +## Usage + + `YAML` +{% highlight yaml %} +{% raw %} +step_name: + type: pending-approval + title: Step Title + description: Step description + timeout: + duration: 2 + finalState: approved + timeUnit: minutes + when: + branch: + only: [ master ] + +{% endraw %} +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ---------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `timeout` | Defines an automatic approval/rejection if a specified amount of time has passed. The `duration` field is hours. By default it is set to 168 (i.e, 7 days). The `finalState` field defines what will happen after the duration time has elapsed. Possible values are `approved`/`denied`/`terminated` | Optional | +| `timeUnit` | This field defines possible options of `minutes`, or `hours`. If the field is not set, the default is `hours` | Optional +| `fail_fast` | If set to false, the pipeline will continue even when the step is rejected | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `when` | Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | + + +## Pausing the Pipeline + +Once the pipeline reaches an approval step it will stop. At this point it **does not** consume any resources. +In the Codefresh UI you will see the *Approve/Reject* buttons. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/build-waiting.png" +url="/images/codefresh-yaml/approval/build-waiting.png" +alt="Build waiting for input" +caption="Build waiting for input" +max-width="80%" +%} + +Once you click any of them the pipeline will continue. Further steps in the pipeline can be enabled/disabled +according to the approval result. + +## Automatic Approvals/Rejections + +By default, a pipeline that contains an approval step will pause for 7 days (168 hours) onces it reaches that step. If you want some automatic action to happen after a specified time period you can define it in advance with the `timeout` property: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + waitForInputBeforeProduction: + type: pending-approval + title: Deploy to Production? + timeout: + duration: 2 + finalState: denied +{% endraw %} +{% endhighlight %} + +This pipeline will wait for approval for two hours. If somebody approves it, it will continue. If nothing happens after two hours +the approval step will be automatically rejected. + +## Approval Restrictions + +By default, any Codefresh user can approve any pipeline that is paused at the approval state. If you want to restrict +the approval action to a subset of people, you can use the [Access Control facilities]({{site.baseurl}}/docs/enterprise/access-control/) that Codefresh provides. + +This is a two-step process. First you need to tag your pipeline with one or more tags (tag names are arbitrary). You can edit tags in the pipeline settings screen. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/pipeline-tag.png" +url="/images/codefresh-yaml/approval/pipeline-tag.png" +alt="Marking a pipeline with tags" +caption="Marking a pipeline with tags" +max-width="40%" +%} + +Once you have tagged your pipelines you can create one or more access rules that restrict approval to specific teams within your organization. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/approval-rule.png" +url="/images/codefresh-yaml/approval/approval-rule.png" +alt="Rules for approvals" +caption="Rules for approvals" +max-width="80%" +%} + + +For more details on access control and users see also the [access control page]({{site.baseurl}}/docs/administration/access-control/). + +## Keeping the Shared Volume after an Approval + +As soon as a pipeline starts waiting for an approval, all contents of the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are lost. Once the pipeline continues running all files that were created manually inside the volume are not available any more. + +If you want to keep any temporary files that were there before the approval, you need to enable the respective policy in your [pipeline settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#policies). + +You can either set this option differently per pipeline, or globally in your account at your [account settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings). + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/keep-volume.png" +url="/images/codefresh-yaml/approval/keep-volume.png" +alt="Preserve Codefresh volume after an approval" +caption="Preserve Codefresh volume after an approval" +max-width="90%" +%} + +>Notice that if you do decide to keep the volume after an approval, the pipeline will still count as "running" against your pricing plan (if you use the SAAS version of Codefresh). If you don't keep the volume, the pipeline is stopped/paused while it is waiting for approval and doesn't count against your pricing plan. We advise you to keep the volume only for pipelines that really need this capability. + +>Notice also that you if you use the [Hybrid version]({{site.baseurl}}/docs/administration/behind-the-firewall/) of Codefresh and your [Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) is setup with local volumes, then the volume will only be present if the dind pod +is scheduled in the same node once the pipeline resumes. Otherwise the volume will not be reused. + +## Controlling the Rejection Behavior + +By default if you reject a pipeline, it will stop right away and it will be marked as failed. All subsequent steps after the approval one will not run at all. + +You might want to continue running the pipeline even when it is rejected by adding the `fail_fast` property in the approval step: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + waitForInputBeforeProduction: + fail_fast: false + type: pending-approval + title: Deploy to Production? +{% endraw %} +{% endhighlight %} + +In this case you can also read the approval result and make the pipeline work differently according to each choice (demonstrated in the following section). + + +## Getting the Approval Result + +As also explained in [step dependencies]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#custom-steps-dependencies) all steps in the Codefresh pipeline belong to a global object +called `steps` (indexed by name). You can read the `result` property for an approval step to see if it was approved or rejected. + +Here is an example: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + askForPermission: + type: pending-approval + title: Destroy QA environment? + destroyQaEnvNow: + image: alpine:3.8 + title: Destroying env + commands: + - echo "Destroy command running" + when: + steps: + - name: askForPermission + on: + - approved +{% endraw %} +{% endhighlight %} + +In this example the second step that is destroying an environment will only run if the user +approves the first step. In case of rejection the second step will be skipped. + +You can follow the same pattern for running steps when an approval step was rejected. +Here is a full example with both cases. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- prepare +- yesPleaseDo +- noDont + +steps: + step_1: + image: alpine:3.8 + title: building chart + stage: prepare + commands: + - echo "prepare" + deployToProdNow: + fail_fast: false + type: pending-approval + title: Should we deploy to prod + stage: prepare + step_2: + image: alpine:3.8 + title: prepare environment + stage: yesPleaseDo + commands: + - echo "world" + when: + steps: + - name: deployToProdNow + on: + - approved + step_3: + image: alpine:3.8 + title: deploy to production + stage: yesPleaseDo + commands: + - echo "world" + when: + steps: + - name: deployToProdNow + on: + - approved + step_4: + image: alpine:3.8 + title: prepare environment + stage: noDont + commands: + - echo "world" + when: + steps: + - name: deployToProdNow + on: + - denied + step_5: + image: alpine:3.8 + title: deploy to staging + stage: noDont + commands: + - echo "world" + when: + steps: + - name: deployToProdNow + on: + - denied +{% endraw %} +{% endhighlight %} + +Here is the pipeline state after a rejection: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/pipeline-rejected.png" +url="/images/codefresh-yaml/approval/pipeline-rejected.png" +alt="Rejecting a pipeline" +caption="Rejecting a pipeline" +max-width="80%" +%} + +>Note that we have added the `fail_fast` property in the approval step because we want the pipeline to continue even when the step is rejected. + + +You can see that only two steps were ignored. If you rerun the pipeline and approve +it, the other two steps will be ignored. + +## Define Concurrency Limits + +Codefresh has the ability to limit the amount of running builds for a specific pipeline with several concurrency policies in the pipeline settings. You can choose if a build that is in a pending approval state will count against the concurrency limits or not. + +As an example let's say that the concurrency limit for a specific pipeline is set to 2. Currently there is one active/running build and a second build that is pending approval. + +1. If the pipeline settings define that builds in pending approval **count** against concurrency, then if you launch a third build it will wait until one of the first two has finished +1. If the pipeline settings define that builds in pending approval **do not** count against concurrency, then if you launch a third build it will execute right away. + +There isn't a correct or wrong way to set this option. It depends on your organization and if your consider builds pending approval as "active" or not. + +You can either set this option [differently per pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#policies), or globally in your account at your [account settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings). + + +## Slack Integration + +If you also enable [Slack integration]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) in Codefresh you will have the choice of approving/rejecting a pipeline +via a Slack channel + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/slack-approval.png" +url="/images/codefresh-yaml/approval/slack-approval.png" +alt="Approval step in a slack channel" +caption="Approval step in a slack channel" +max-width="80%" +%} + +To enable this behavior, you need to activate it in the Slack settings page: + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/approval/slack-settings.png" +url="/images/codefresh-yaml/approval/slack-settings.png" +alt="Slack settings" +caption="Slack settings" +max-width="50%" +%} + +Also, if you run a pipeline manually that includes an approval step you should check +the "Report notification of pipeline execution" checkbox as explained in [Monitoring Pipelines]( +{{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/#monitoring-pipelines-outside-the-codefresh-ui). + + + +## What to read next + +- [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) +- [Advanced Workflows ]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +- [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) + + diff --git a/_docs/pipelines/steps/build.md b/_docs/pipelines/steps/build.md new file mode 100644 index 00000000..e432275c --- /dev/null +++ b/_docs/pipelines/steps/build.md @@ -0,0 +1,380 @@ +--- +title: "Build" +description: "Building Docker images in Codefresh pipelines" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/build-1/ + - /docs/codefresh-yaml/steps/build-1/ +toc: true +--- +Use Docker to build an image and store it in Codefresh. + +## Purpose of build steps + +In Codefresh, docker containers are first-class citizens +and special typed steps are offered for the most usual docker commands. Build steps are a secure replacement for `docker build` commands. + +Therefore, this command on your local workstation: + +``` +docker build . -t my-app-image:1.0.1 +``` + +will become in Codefresh the following build step. + +```yaml +BuildMyImage: + title: Building My Docker image + type: build + image_name: my-app-image + tag: 1.0.1 +``` + +## Usage + + `YAML` +{% highlight yaml %} +step_name: + type: build + title: Step Title + description: Free text description + working_directory: {% raw %}${{clone_step_name}}{% endraw %} + dockerfile: path/to/Dockerfile + image_name: owner/new-image-name + tag: develop + build_arguments: + - key=value + target: stage1 + no_cache: false + no_cf_cache: false + tag_policy: original + fail_fast: false + metadata: + set: + - qa: pending + when: + condition: + all: + noDetectedSkipCI: "includes('{% raw %}${{CF_COMMIT_MESSAGE}}{% endraw %}', '[skip ci]') == false" + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `working_directory` | The directory in which the build command is executed. It can be an explicit path in the container's file system, or a variable that references another step.
The default is {% raw %} `${{main_clone}}` {% endraw %}. This only changes the Docker build context and is unrelated to the `WORKDIR` inside the Dockerile | Default | +| `dockerfile` | The path to the `Dockerfile` from which the image is built. The default is `Dockerfile`. | Default | +| `image_name` | The name for the image you build. | Required | +| `region` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The names of the regions for which to perform cross-region replication. The names of the source region and the destination region name must be defined in separate steps. | Optional | +| `tag` | The tag that is assigned to the image you build.
The default is the name of the branch or revision that is built. | Default | +| `tags` | Multiple tags under which to push the image. Use either this or `tag`. This is an array, so should be of the following style:
{::nomarkdown}
tags:
- tag1
- tag2
- {% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}
- tag4
{:/}or
{::nomarkdown}
tags: [ 'tag1', 'tag2', '{% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}', 'tag4' ]
{:/} | Optional | +| `registry` | The registry logical name of one of the inserted registries from the integration view.
The default value will be your default registry [if you have more than one]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). | Optional | +| `registry_contexts` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | +|`disable_push` | Do not push to any registry automatically. | Optional | +|`tag_policy` | Push the tag name without change or lowercase it automatically. By default `tag: MixedCase` will be pushed as `image_name:mixedcase`. Possible options are `original` and `lowercase`. Default is `lowercase` | Default | +| `no_cache` | Disable Docker engine cache for the build [more info](https://codefresh.io/docs/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) | Optional | +| `no_cf_cache` | Disable Codefresh build optimization for the build [more info](https://codefresh.io/docs/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) +| `build_arguments` | A set of [Docker build arguments](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg) to pass to the build process. | Optional | +| `target` | target stage in a multistage build (build will run until this stage) | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions that need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `metadata` | Annotate the built image with [key-value metadata]({{site.baseurl}}/docs/docker-registries/metadata-annotations/). | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | +| `buildkit` | Set to `true` to enable [Buildkit]({{site.baseurl}}/docs/codefresh-yaml/steps/build/#buildkit-support) and all of its enhancements | Optional | + +**Exported resources:** +- Working Directory +- Image ID + +## Examples + +Build an image using a Dockerfile in the root project folder: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build +{% endhighlight %} + +Build an image using a different Dockerfile and a specific version tag + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + type: build + image_name: my-app-image + dockerfile: my-custom.Dockerfile + tag: 1.0.1 +{% endhighlight %} + +Build an image using a different Dockerfile and push multiple tags to the default registry. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + type: build + image_name: my-app-image + dockerfile: my-custom.Dockerfile + tags: + - latest + - ${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}} + - v1.1 +{% endraw %} +{% endhighlight %} + +Build an image and automatically push to the [registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) with name `my-registry`. + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + type: build + image_name: my-app-image + dockerfile: my-custom.Dockerfile + tag: 1.0.1 + registry: my-registry +{% endhighlight %} + +Build two images in two different folders using [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) as tags. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + BuildNodeImage: + title: Building My Node app + type: build + image_name: my-department/my-team/my-node-image + dockerfile: Dockerfile + working_directory: ./project1 + tag: ${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}} + BuildGoImage: + title: Building My Go app + type: build + image_name: my-company/my-go-image + dockerfile: Dockerfile + working_directory: ./project2 + tag: ${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}} +{% endraw %} +{% endhighlight %} + +It also possible to build Docker images in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) for faster builds. + +### Inline Dockerfile + +If your project does not already have a Dockerfile, you can also define one within the pipeline: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + BuildingDockerImage: + title: Building Docker Image + type: build + image_name: my-own-go-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: + content: |- + # --- + # Go Builder Image + FROM golang:1.8-alpine AS builder + # set build arguments: GitHub user and repository + ARG GH_USER + ARG GH_REPO + # Create and set working directory + RUN mkdir -p /go/src/github.com/$GH_USER/$GH_REPO + # copy file from builder image + COPY --from=builder /go/src/github.com/$GH_USER/$GH_REPO/dist/myapp + /usr/bin/myapp + CMD ["myapp", "--help"] +{% endraw %} +{% endhighlight %} + +Use this technique only as a last resort. It is better if the Dockerfile exists as an actual file in source control. + + +## Automatic pushing + +All images built successfully with the build step, will be automatically pushed to the default Docker registry in your account. This behavior is completely automatic and happens without any extra configuration on your part. If you want to disable this then add the `disable_push` property in your build step. + +>Notice that the [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) in Codefresh is optional and is only needed if you want to push to [external Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). + +{% + include image.html + lightbox="true" + file="/images/artifacts/cfcr/codefresh-registry-list.png" + url="/images/artifacts/cfcr/codefresh-registry-list.png" + alt="Docker Images pushed automatically" + caption="Docker Images pushed automatically" + max-width="80%" +%} + +## Buildkit support + +Codefresh also allows you to use [buildkit](https://github.com/moby/buildkit) with all its [enhancements](https://docs.docker.com/develop/develop-images/build_enhancements/) and [experimental features](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#experimental-syntaxes). + +Using buildkit you can get: + +* Improved build output logs +* Mounting of external secrets that will never be stored in the image +* Access to SSH keys and sockets from within the Dockerfile +* Use cache and bind-mounts at build time + +These capabilities are offered as extra arguments in the build step and using any of them will automatically enable buildkit. You can utilize the different mount-options for the Dockerfile instruction `RUN` as long as buildkit is enabled for your build step. Mounts of type [`cache`](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#example-cache-go-packages) work out of the box and are persisted between pipeline runs. + +The simplest way to use buildkit is by enabling it explicitly: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + buildkit: true +{% endhighlight %} + +Buildkit is also automatically enabled if you use any of its features such as the `progress` property: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + progress: tty +{% endhighlight %} + +Possible values for `progress` are `tty` and `plain`. + +For secrets you can either mention them in a single line: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + secrets: + - id=secret1,src=./my-secret-file1.txt + - id=secret2,src=./my-secret-file2.txt +{% endhighlight %} + +or multiple lines: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + secrets: + - id: secret1 + src: ./my-secret-file1.txt + - id: secret2 + src: ./my-secret-file2.txt +{% endhighlight %} + +For the SSH connection you can either use the default: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + ssh: default +{% endhighlight %} + + +or define different keys: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + ssh: + - github=~/.ssh/github_rsa + - bitbucket=~/.ssh/bitbucket_rsa +{% endhighlight %} + +You might want to use an environment variable to store and retrieve a ssh key. This can be achieved by converting you ssh key into a one-line string: +``` +tr '\n' ',' < /path/to/id_rsa +``` + +Copy the output and place it an [environment variable]({{site.baseurl}}/docs/codefresh-yaml/variables/#user-provided-variables). To make the SSH key availabe to the build step, you can write it to the codefresh volume: +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + SetupSshKeys: + title: Setting up ssh key + image: alpine:latest + commands: + - mkdir /codefresh/volume/keys + - echo "${SSH_KEY}" | tr ',' '\n' > /codefresh/volume/keys/github_rsa + + BuildMyImage: + title: Building My Docker image + image_name: my-app-image + type: build + tag: latest + ssh: + - github=/codefresh/volume/keys/github_rsa +{% endraw %} +{% endhighlight %} + + +You can combine all options (`ssh`, `progress`, `secrets`) in a single build step if desired. + + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline Steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) diff --git a/_docs/pipelines/steps/composition.md b/_docs/pipelines/steps/composition.md new file mode 100644 index 00000000..75e75899 --- /dev/null +++ b/_docs/pipelines/steps/composition.md @@ -0,0 +1,434 @@ +--- +title: "Composition" +description: "Run a Docker container with its dependencies inside a pipeline" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/composition-1/ + - /docs/codefresh-yaml/steps/composition-1/ +toc: true +--- +The composition step runs a Docker Composition as a means to execute finite commands in a more complex interaction of services. + +>Note that while composition steps are still supported, the recommended way to run integrations tests going forward is with [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/). + +## Motivation for Compositions + +The primary purpose of compositions is to run tests that require multiple services for their execution (often known as integration tests). + +The syntax offered by Codefresh closely follows the syntax for [Docker-compose](https://docs.docker.com/compose/overview/) files, but is technically not 100% the same (there are some important differences). However, if you are already familiar with Docker compose, you will be immediately familiar with Codefresh compositions. + +> Codefresh only understands Docker compose versions [2](https://docs.docker.com/compose/compose-file/compose-file-v2/) and [3](https://docs.docker.com/compose/compose-file/), but not point releases such as 2.1. + +The big difference between the Codefresh and Docker compose is that Codefresh is distinguishes between two kinds of services: + +* Composition Services +* Composition Candidates + +**Composition Services** are helper services that are needed for the tests to run. These can be a database, a queue, a cache, or the backend docker image of your application -- these closely parallel the services that you might define in Docker compose. + +**Composition Candidates** are special services that will execute the tests. Codefresh will monitor their execution and the build will fail if they do not succeed. Composition candidates are almost always Docker images that contain unit/integration tests or other kinds of tests (e.g. performance) + +You need at least one composition service and one candidate for the composition step. + + +## Usage + +Here is an example of a composition step. Note that there is one composition service (PostgreSQL database, named `db`) and one composition candidate (tests executed with gulp) + +The most important part is the `command` line that executes the tests: `command: gulp integration_test`. If it fails, then the whole composition step will fail. + + + + `codefresh.yml` +{% highlight yaml %} +step_name: + type: composition + title: Step Title + description: Free text description + working_directory: {% raw %}${{a_clone_step}}{% endraw %} + composition: + version: '2' + services: + db: + image: postgres + composition_candidates: + test_service: + image: {% raw %}${{build_step}}{% endraw %} + command: gulp integration_test + working_dir: /app + environment: + - key=value + composition_variables: + - key=value + fail_fast: false + when: + condition: + all: + notFeatureBranch: 'match("{% raw %}${{CF_BRANCH}}{% endraw %}", "/FB-/", true) == false' + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endhighlight %} + +## Caveats on sharing a docker-compose.yml + +Although Codefresh's composition syntax closely follows the syntax used in `docker-compose.yml` files, it is not 100% the same. If you are using `docker-compose.yml` locally, you may experience some problems if you try to have Codefresh reference the file (by passing it as an argument to `compose`, e.g. `compose: docker-compose.yml`). + +One subtle difference is that Docker compose will interpolate environment variables that are quoted in single-braces, e.g. `${DATABASE_URL}`, whereas Codefresh interpolates variables that are quoted in double-braces, e.g. {% raw %}`${{DATABASE_URL}}`{% endraw %}. So if your `docker-compose.yml` file relies on the parsing of ENV variables, it may not be a good candidate for sharing with Codefresh. + +## Fields + +The following describes the fields available in a step of type `composition` + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `working_directory` | The directory in which to search for the composition file. It can be an explicit path in the container's file system, or a variable that references another step. The default is {% raw %}`${{main_clone}}`{% endraw %}. Note that this is completely different from `working_dir` which is on the service level. | Default | +| `composition` | The composition you want to run. This can be an inline YAML definition or a path to a composition file on the file system, e.g. `docker-compose.yml`, or the logical name of a composition stored in the Codefresh system. We support most features of [Docker compose version 2.0](https://docs.docker.com/compose/compose-file/compose-file-v2/) and [3.0](https://docs.docker.com/compose/compose-file/) | Required | +| `version` | Version for docker compose. Use `2` or `3` | Required | +| `composition_candidates` | The definition of the service to monitor. Each candidate has a **single** `command` parameter that decides what will be tested. | Required | +| `environment` (service level) | environment that will be accessible to the container | Optional | +| `working_dir` (service level) | defines the working directory that will be used in a service before running a command. By default it is defined by the docker image that is used by the service. | Optional | +| `registry_contexts` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | +| `volumes` (service level) | Extra volumes for individual services. Used for transferring information between your steps. Explained in detail later in this page. | Optional | +| `composition_variables` | A set of environment variables to substitute in the composition. Notice that these variables are docker-compose variables and **NOT** environment variables | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +## Composition versus Composition Candidates + +For Codefresh to determine if the step and operations were successfully executed, you must specify at least one `composition_candidate`. + +A `composition_candidate` is a single service component of the normal Docker composition that is monitored for a successful exit code and determines the outcome of the step. During runtime, the `composition_candidate` is merged into the specified `composition`and is monitored for successful execution. + +The critical part of each candidate is the `command` parameter. This takes [a single command](https://docs.docker.com/compose/compose-file/#command) that will +be executed inside the Docker container of the candidate and will decide if the whole composition is successful or not. Only one command is allowed (similar to Docker compose). If you wish to test multiple commands you need to connect them with `&&` like this. + +{% highlight yaml %} + composition_candidates: + my_unit_tests: + image: node + command: bash -c "sleep 60 && pwd && npm run test" +{% endhighlight %} + + +## Working directories in a composition + +By default, all services that take part in a composition will use as working directory the one defined by the respective image. If you want to change that, you need to use the `working_dir` parameter at the service level. + +Here is an example: + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + my_composition: + type: composition + title: Sample composition + composition: + version: '2' + services: + my_service: + image: alpine + command: 'pwd' + working_dir: /tmp + composition_candidates: + my_test_service: + image: python + working_dir: /root + command: 'pwd' +{% endhighlight %} + +If you run this composition, you will see in the logs that the alpine image will use `/tmp` as a working directory and the python one will use `/root` + +``` +my_service_1 | /tmp +my_test_service_1 | /root +``` + +## Composition networking + +The networking in Codefresh compositions works just like normal Docker-compose. Each service is assigned a hostname that matches +its name and is accessible by other services. + +Here is an example + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + build_step: + type: build + image_name: my-node-app + dockerfile: Dockerfile + tag: ${{CF_BRANCH}} + my_db_tests: + type: composition + composition: + version: '2' + services: + db: + image: mysql:latest + ports: + - 3306 + environment: + MYSQL_ROOT_PASSWORD: admin + MYSQL_USER: my_user + MYSQL_PASSWORD: admin + MYSQL_DATABASE: nodejs + composition_candidates: + test: + image: ${{build_step}} + links: + - db + command: bash -c 'sleep 30 && MYSQL_ROOT_PASSWORD=admin MYSQL_USER=my_user MYSQL_HOST=db MYSQL_PASSWORD=admin MYSQL_DATABASE=nodejs npm test' +{% endraw %} +{% endhighlight %} + +In this composition the MySql instance will be available at host `db:3306` accessible from the node image. When the node tests run, they will be pointed to that host and port combination to access it. + +Notice also that like docker compose the order that the services are launched is not guaranteed. A quick way to solve this issue +is with a sleep statement like shown above. This will make sure that the database is truly up before the tests run. + +A better approach would be to use solutions such as [wait-for-it](https://github.com/vishnubob/wait-for-it) which are much more robust. Here is an example: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + build_image: + type: build + description: Building the image... + image_name: my-spring-boot-app + tag: ${{CF_BRANCH_TAG_NORMALIZED}} + build_image_with_tests: + type: build + description: Building the Test image... + image_name: maven-integration-tests + dockerfile: Dockerfile.testing + integration_tests: + type: composition + title: Launching QA environment + description: Temporary test environment + composition: + version: '2' + services: + app: + image: ${{build_image}} + ports: + - 8080 + composition_candidates: + test_service: + image: ${{build_image_with_tests}} + links: + - app + command: bash -c '/usr/bin/wait-for-it.sh -t 20 app:8080 -- mvn verify -Dserver.host=app' +{% endraw %} +{% endhighlight %} + +In this composition a Java application is launched at `app:8080` and then a second image is used for integration tests that target that URL (passed as a parameter to Maven). + +The `wait-for-it.sh` script will make sure that the Java application is truly up before the tests are started. Notice that in the example above the script is included in the testing image (created by `Dockerfile.testing`) + +## Using public Docker images in a composition + +It is important to notice that Docker images used in a composition (both as services and candidates) will be looked from your connected registries first before looking at Dockerhub: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + my_composition: + type: composition + title: Sample composition + composition: + version: '2' + services: + my_service: + image: mysql + ports: + - 3306 + composition_candidates: + my_test_service: + image: alpine + working_dir: /root + command: 'pwd' + +{% endraw %} +{% endhighlight %} + +In the example above if you already have two images in your private registries named `mysql` and `alpine`, then *THEY* will be used instead of the respective images in Dockerhub. + +You can see which images are used in the logs of the builds: + +``` +Running composition step: Sample composition +Pulling kostisazureregistry.azurecr.io/mysql@sha256:1ee5515fed3dae4f13d0f7320e600a38522fd7e510b225e68421e1f90 +Pulling kostisazureregistry.azurecr.io/alpine@sha256:eddb7866364ec96861a7eb83ae7977b3efb98e8e978c1c9277262d327 +``` + + +## Accessing your project folder from a composition + +By default, the services of a composition run in a completely isolated manner. There are several scenarios however where you wish to access your Git files such as: + +* Using test data that is available in the project folder +* Preloading a database with a data script found in Git +* Running integration tests and then using their [results for reporting]({{site.baseurl}}/docs/testing/test-reports/) + +The Codefresh [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automatically mounted in [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) but **NOT** in compositions. You have to mount it yourself if you use that functionality. + +Here is an example where the shared volume is mounted in a composition -- {% raw %}`'${{CF_VOLUME_NAME}}:${{CF_VOLUME_PATH}}'`{% endraw %} is listed under `volumes`: + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + create_test_data_step: + title: Creating dummy data + image: alpine + commands: + - echo "Writing in shared volume" > /codefresh/volume/sample_text.txt + my_sample_composition: + type: composition + title: Composition with volume + composition: + version: '2' + services: + my_sample_service: + image: node + volumes: + - '${{CF_VOLUME_NAME}}:${{CF_VOLUME_PATH}}' + working_dir: '${{CF_VOLUME_PATH}}' + command: bash -c "pwd && cat sample_text.txt" + composition_candidates: + my_unit_tests: + image: python + volumes: + - '${{CF_VOLUME_NAME}}:${{CF_VOLUME_PATH}}' + working_dir: '${{CF_VOLUME_PATH}}' + command: bash -c "pwd && echo 'Finished tests' > test_result.txt" + read_test_data_step: + title: Reading dummy data + image: alpine + commands: + - ls -l /codefresh/volume + - cat /codefresh/volume/test_result.txt +{% endraw %} +{% endhighlight %} + +In this pipeline: + +1. The first freestyle step writes a simple test file in the shared volume. +1. The composition starts and both services (`my_sample_service` and `my_unit_tests`) attach the same volume. +1. The sample service reads from the shared volume (i.e. using test data that was created before). +1. The sample unit test service writes to the shared volume (emulating test results). +1. The last freestyle step reads the file that was written by the composition. + +Therefore, in this pipeline you can see both ways of data sharing, bringing files into a composition and getting results out of it. Notice that we need to mount the shared volume only in the composition services. The freestyle steps automatically mount `/codefresh/volume` on their own. + + +>Note: In order to mount the shared volume in one of your composition services, you must mount it in the `composition_candidate` also. It is not compulsory to mount the shared volume in all services of a composition. Only those that actually use it for file transfer, should mount it. + + +## Composition variables versus environment variables + +Docker compose supports [two kinds of variables in its syntax](https://docs.docker.com/compose/environment-variables/): + +* There are environment variables that are used in the docker-compose file itself (`${VAR}` syntax). +* There are environment variables that are passed in containers (`environment:` yaml group). + +Codefresh supports both kinds, but notice that variables mentioned in the +`composition_variables` yaml group refer to the *first* kind. Any variables defined there are **NOT** passed automatically to containers (use the `environment` yaml group for that purpose). + +This can be illustrated with the following example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + comp1: + type: composition + title: Composition example 1 + description: Free text description + composition: + version: '2' + services: + db: + image: alpine + composition_candidates: + test_service: + image: alpine + command: printenv + environment: + - FIRST_KEY=VALUE + composition_variables: + - ANOTHER_KEY=ANOTHER_VALUE +{% endraw %} +{% endhighlight %} + +If you run the compositio,n you will see that the `printenv` command shows the following: + +``` +test_service_1 | FIRST_KEY=VALUE +``` + +The `FIRST_KEY` variable which is defined explicitly in the `environment` yaml part is correctly passed to the alpine container. The `ANOTHER_KEY` is not visible in the container at all. + +You should use the `composition_variables` yaml group for variables that you wish to reuse in other parts of your composition using the `${ANOTHER_KEY}` syntax. + +## Merging services + +If the `composition` already contains a service with the same name as the `composition_candidate`, the two service definitions are combined, with preference given to the `composition_candidate`'s definition. + +For example, we create a new Codefresh composition named 'test_composition': + + `test-composition.yml` +{% highlight yaml %} +version: '2' + services: + db: + image: postgres + test_service: + image: myuser/mytestservice:latest + command: gulp integration_test +{% endhighlight %} + +Now we want to reuse this composition during our build for testing purposes. +We can add the following composition step to our `codefresh.yml` file and define the composition step so that `test_service` always uses the latest image that was built. + + `YAML` +{% highlight yaml %} +run_tests: + type: composition + composition: test_composition + composition_candidates: + test_service: + image: {% raw %}${{build_step}}{% endraw %} +{% endhighlight %} + +In the above example, both `composition` and `composition_candidates` define a service named `test_service`. After merging these definitions, `test_service` will maintain the `command` that was defined in the original composition but will refer to the image built by the step named `build_step`. + +## What to read next + +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) +* [Introduction to pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) diff --git a/_docs/pipelines/steps/deploy.md b/_docs/pipelines/steps/deploy.md new file mode 100644 index 00000000..a3a2fe0e --- /dev/null +++ b/_docs/pipelines/steps/deploy.md @@ -0,0 +1,184 @@ +--- +title: "Deploy" +description: "Deploying to Kubernetes from a Codefresh pipeline" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/deploy/ +toc: true +--- +The *Deploy* step can be used as a step to deploy a pre-built Docker image to a cluster + +This step allows to (re)deploy a Kubernetes application in your cluster + +It has two modes: + +1. Using the `service` option. In this case it will redeploy to an [existing service/deployment in your cluster]({{site.baseurl}}/docs/getting-started/deployment-to-kubernetes-quick-start-guide/) . Codefresh will +automatically update the service/deployment with the new docker image. +1. Using the `file_path` option. In this case you provide your own Kubernetes manifest and Codefresh deploys it as-is. It is **your +own responsibility** to do [custom replacements]({{site.baseurl}}/docs/deploy-to-kubernetes/kubernetes-templating/) here (for example using [awk](https://en.wikipedia.org/wiki/AWK), [sed](https://www.gnu.org/software/sed/manual/sed.html) or [yq](http://mikefarah.github.io/yq/)). The deploy step is also using the [Codefresh templating mechanism]({{site.baseurl}}/docs/deploy-to-kubernetes/kubernetes-templating/#using-the-codefresh-deploy-image) behind the scenes if you want to take advantage of it. For a full templating solution we also +suggest you look at [Helm]({{site.baseurl}}/docs/getting-started/helm-quick-start-guide/). + +You need to define either one of these fields in the deploy step. If you define `service` you also can select the exact Docker image +with the `candidate` field (otherwise Codefresh will just reuse the docker image defined in the existing deployment) + +## Usage + + `YAML` +{% highlight yaml %} + step_name: + title: deploying to cluster + type: deploy + kind: kubernetes + ## cluster name as the shown in account's integration page + cluster: --my-cluster-name-- + # desired namespace + namespace: default + + ## Two ways to distinguish which deployment YAML to deploy - service or file_path: + # The Kubernetes service that associated with the deployment using selector + service: --my-service-- + # Path to deployment.yml location inside the image volume + file_path: ./deployment.yml + # In seconds, how long the step will wait until the rolling update is complete (default is 120) + timeout: '150' + # Candidate is optional, if not specified will redeploy the same image that specified in the deployment file + # When candidate exists it should have both: image and registry + candidate: + # The image that will replace the original deployment image + # The image that been build using Build step + image: {% raw %}${{build_step}}{% endraw %} + # The registry that the user's Kubernetes cluster can pull the image from + # Codefresh will generate (if not found) secret and add it to the deployment so the Kubernetes master can pull it + registry: dockerhub + # Condition to run the step + when: + branch: + only: + - master + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ---------------------------------------------------------- -------- | ------------------------- | +| `title` | The free-text display name of the step | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `kind` | Currently only `kubernetes` is supported | Required | +| `cluster` | Name of your K8s cluster as found in the dashboard | Required | +| `namespace` | Namespace where the deployment will take place | Required | +| `service` | Name of the existing service that will updated. You need to provide `service` OR `file_path` | Required/Optional | +| `file_path` | A deployment manifest. You need to provide `service` OR `file_path` | Required/Optional | +| `timeout` | Seconds to wait for the deployment to be completed. Default is 120 seconds | Default | +| `candidate` | Docker image that will be deployed. Only valid if `service` is defined. Should contain `image` and name of registry as it appears in the [registry integration page]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +## Examples + +Update an existing service using the same Docker image (tagged with branch) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: python-flask-sample-app + working_directory: ./ + tag: ${{CF_BRANCH_TAG_NORMALIZED}} + dockerfile: Dockerfile + deploy_to_k8: + title: deploying to cluster + type: deploy + kind: kubernetes + cluster: myDemoAKSCluster + namespace: demo + service: my-python-app +{% endraw %} +{% endhighlight %} + +Update an existing service using a different Docker image (tagged with git hash) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: python-flask-sample-app + working_directory: ./ + tag: ${{CF_SHORT_REVISION}} + dockerfile: Dockerfile + deploy_to_k8: + title: deploying to cluster + type: deploy + kind: kubernetes + cluster: myDemoAKSCluster + namespace: demo + service: my-python-app + candidate: + # The image that will replace the original deployment image + # The image that been build using Build step + image: ${{MyAppDockerImage}} + # The registry that the user's Kubernetes cluster can pull the image from + # Codefresh will generate (if not found) secret and add it to the deployment so the Kubernetes master can pull it + registry: cfcr +{% endraw %} +{% endhighlight %} + + +Deploy a custom Kuberentes Manifest as is. (Only a deployment will be created) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: python-flask-sample-app + working_directory: ./ + tag: ${{CF_BRANCH}} + dockerfile: Dockerfile + deploy_to_k8: + title: deploying to cluster + type: deploy + kind: kubernetes + cluster: myDemoAKSCluster + namespace: demo + file_path: ./deploy/deployment.yml +{% endraw %} +{% endhighlight %} + +## Advanced Kubernetes deployments + +If you find the deploy step limited, feel free to look at the other deployment options offered by Codefresh: + +* [The cf-deploy-kubernetes step]({{site.baseurl}}/docs/deploy-to-kubernetes/kubernetes-templating/) +* [Custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) +* [Helm]({{site.baseurl}}/docs/getting-started/helm-quick-start-guide/) + +## What to read next +- [Kubernetes Quick start guide]({{site.baseurl}}/docs/getting-started/deployment-to-kubernetes-quick-start-guide/) +- [Manage your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/) +- [Install HELM chart using Codefresh pipeline]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) + + diff --git a/_docs/pipelines/steps/freestyle.md b/_docs/pipelines/steps/freestyle.md new file mode 100644 index 00000000..8d0723fa --- /dev/null +++ b/_docs/pipelines/steps/freestyle.md @@ -0,0 +1,353 @@ +--- +title: "Freestyle" +description: "Run commands inside a Docker container" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/freestyle/ +toc: true +--- +The Freestyle step is designed so you can execute a series of commands in a container. Freestyle steps +are the bread and butter of [Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). + +## Purpose of freestyle steps + +In Codefresh, docker containers are first-class citizens +and special typed steps are offered for the most usual docker commands. Freestyle steps are a secure replacement for `docker run` commands. + + +Therefore, this command on your local workstation: + +``` +docker run python:3.6.4-alpine3.6 pip install . +``` + +will become in Codefresh the following freestyle step. + +```yaml +CollectAllMyDeps: + title: Install dependencies + image: python:3.6.4-alpine3.6 + commands: + - pip install . +``` + + +Select an image to start a container, then you can specify a working directory, and commands. +If you do not specify a working directory or commands, the step runs the organic commands specified by the image. +In all freestyle steps Codefresh automatically [uses a shared docker volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that contains your git source code. + +## Usage + + `YAML` +{% highlight yaml %} +{% raw %} +step_name: + title: Step Title + description: Step description + image: image/id + working_directory: ${{step_id}} + commands: + - bash-command1 + - bash-command2 + cmd: + - arg1 + - arg2 + environment: + - key=value + entry_point: + - cmd + - arg1 + shell: sh + fail_fast: false + volumes: + - ./relative-dir-under-cf-volume1:/absolute-dir-in-container1 + - ./relative-dir-under-cf-volume2:/absolute-dir-in-container2 + when: + branch: + only: [ master ] + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endraw %} +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `image` | The image from which the executable container is created. It can be an explicit ID of a Docker image, or a variable that references a **Build** or **Push** step. | Required | +| `working_directory` | The directory from which the commands are executed. It can be an explicit path in the container's file system, or a variable that references another step. The default `working_directory` is the cloned repository directory and not the working directory specified by the image. If you need to use the default working directory of the image use `IMAGE_WORK_DIR`. | Default | +| `commands` | One or more commands to execute in a shell in the container, as array of strings. | Optional | +| `cmd` | docker CMD arguments to use along with the container entry point. can be string or array of strings. | Optional | +| `entry_point` | Override the default container entry point. can be string or array of strings. | Optional | +| `shell` | Explicitly set the executing shell to bash or sh. If not set the default will be sh. Note the `bash` option requires that you specify an `image` that includes `/bin/bash`; many images do not. | Optional | +| `environment` | A set of environment variables for the container. | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `registry_context` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | +| `volumes` | One or more volumes for the container. All volumes must be mounted from the existing shared volume (see details below) |Optional +| `when` | Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +**Exported resources:** +- Working Directory. + +## Examples + +Here are some full pipelines with freestyle steps. Notice that in all cases the pipelines are connected to [git repositories]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-creation-modes) +so the source code is already checked out and available to all pipeline steps. + +**Creating a [JAR file]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/):** + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + my_jar_compilation: + title: Compile/Unit test + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository package +{% endhighlight %} + +Note how we [cache Maven dependencies]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/#caching-the-maven-dependencies) using the internal Codefresh Volume. + +**Running unit tests in [Node.JS]({{site.baseurl}}/docs/learn-by-example/nodejs/):** + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + my_node_app: + title: Running unit tests + image: node:11 + commands: + - npm install + - npm run test +{% endhighlight %} + +**Packaging a [GO application]({{site.baseurl}}/docs/learn-by-example/golang/golang-hello-world/):** + +`codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + my_go_app: + title: Compiling GO code + image: golang:1.7.1 + commands: + - go get github.com/example-user/example-repo + - go build +{% endhighlight %} + +**Performing a [blue/green deployment](https://github.com/codefresh-io/k8s-blue-green-deployment):** + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + blueGreenDeploy: + title: Deploying new version + image: codefresh/k8s-blue-green:master + environment: + - SERVICE_NAME=my-demo-app + - DEPLOYMENT_NAME=my-demo-app + - NEW_VERSION=${{CF_SHORT_REVISION}} + - HEALTH_SECONDS=60 + - NAMESPACE=colors + - KUBE_CONTEXT=myDemoAKSCluster +{% endraw %} +{% endhighlight %} + +## Dynamic freestyle steps + +Codefresh has the unique ability to allow you to run freestyle steps in the context of a docker image +created on the same pipeline. This means that you can dynamically [create docker images]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) on demand within the pipeline +that needs them. + +Creating a custom docker image with extra tools (Terraform and Ansible) + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + CreateMyCustomImage: + title: Creating custom Docker image + type: build + dockerfile: tf_and_ansible.Dockerfile + image_name: my-iac-tools-container + UseMyCustomImage: + title: Running IAC tools + image: ${{CreateMyCustomImage}} + commands: + - terraform --version + - ansible --version +{% endraw %} +{% endhighlight %} + +Here the `UseMyCustomImage` freestyle step is running in the [context]({{site.baseurl}}/docs/codefresh-yaml/variables/#context-related-variables) of the Docker image that was created in the previous step. +In fact, a very common pattern that you will see in Codefresh pipelines is the executions of [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) in the image that was created in a build step: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-own-app + MyUnitTests: + title: Running Unit tests + image: ${{MyAppDockerImage}} + commands: + - ./my-unit-tests.sh +{% endraw %} +{% endhighlight %} + +Here the `MyAppDockerImage` step is creating a custom docker image. That image is used to run the `MyUnitTests` step. +This pattern works very well for cases where testing tools are already part of the image (usually with dynamic languages). +In other case you can have a second Dockerfile in your application that is designed explicitly to hold all your testing tools. + +## Entry point + +When using the original container entry point, you can use the `cmd` field to specify additional arguments to be used with the entry point. This can be a string, or an array of strings. For example: + +```yaml +image: mwendler/cowsay +cmd: + - "Hello" +``` + +is equivalent to running `docker run mwendler/cowsay Hello` which is equivalent to running `cowsay Hello` inside the container. + + +You can override the container's default entry point using the `entry_point` field. This can be a string, or an array of strings. For example: + +```yaml + +image: mwendler/cowsay +entry_point: + - echo + - Hello +``` + +## Commands + +When you use the `commands` field, it will override the container original `entry_point` and will execute the commands in a shell inside the container. +The provided commands are concatenated into a single command using the shell's `;` operator, and are run using the default shell `/bin/sh` as an entry point. +Additional settings that are set only when using commands are `set -e`, and the [`cf_export`]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) utility. + +> Using complex commands in the freestyle step requires use of [YAML block scalars](http://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines). + +### Commands and Entry point + +If you want to retain the original entry point, do not use the `commands` field. + +However, this example: + +```yaml +image: mwendler/cowsay +commands: + - "Hello" +``` + +will cause and error because the engine will attempt to run the command `Hello` in a shell inside the container, and the command `Hello` is not a valid command. +In order to use the `commands` form with an `entrypoint` enabled container, you can add the commands from the entry point to the list of commands, like so: + +```yaml +image: mwendler/cowsay +commands: + - cowsay "Hello" +``` + +## Custom volumes + +If you are familiar with [Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) you should know that all freestyle steps automatically share a [volume](https://docs.docker.com/storage/) mounted at `/codefresh/volume` which can be used to transfer data (e.g. dependencies and test results) from each step to the next. + +**This volume is automatically mounted by Codefresh and needs no configuration at all**. All you have to do to access it, is read/write the `/codefresh/volume` folder from your application. This folder also [includes by default the source code]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) of the git repository connected to the pipeline (at the `/codefresh/volume/` subfolder) + +You can use the `volumes` property to create your own custom volumes that can be mounted in different folders. **For security reasons however all source volume data (i.e. the "host" folder) still needs to be bound with `/codefresh/volume` or any of its subdirectories**: + +Attempting to mount a folder outside of `/codefresh/volume` will result in an error. + +### Simple volume example + +Let's assume that your application expects to find a configuration folder at `/config`. The folder however that contains the needed files in GIT is under `my-app-repo/my-sample-config`. When the application is checked out the files actually reside at `/codefresh/volume/my-app-repo/my-sample-config`. + +You can still run your application without any code changes by doing the following bind: + +```yaml +title: Running my application with custom volume +image: my-docker-app:latest +volumes: + - ./my-app-repo/my-sample-config:/config # host path is relative to /codefresh/volume +``` + +Now the `my-docker-app` application will run and find all its needed files at `/config`. + +Notice that we use a relative path here but even if you used an absolute one (`/my-app/my-sample-config`) the result would be the same because Codefresh does not allow you to bind anything outside the shared Codefresh volume. + +### Injecting custom folders in a running container + +Here is another example pipeline with two steps. The first one creates a custom config file in the shared Codefresh volume (that is always available) at `/codefresh/volume/my-config`. The second step reads the config file at a different folder in `/my-own-config-folder-injected`. + +```yaml +version: '1.0' +steps: + CreateCustomConfiguration: + title: Creating configuration + image: alpine + commands: + - mkdir -p /codefresh/volume/my-config + - echo "foo=bar" > /codefresh/volume/my-config/custom.txt + - ls /codefresh/volume/my-config + InjectConfiguration: + title: Reading configuration + image: alpine + commands: + - ls /codefresh/volume/my-config # Codefresh default volume shared between all steps + - ls /my-own-config-folder-injected # Special volume just for this container + - cat /my-own-config-folder-injected/custom.txt + volumes: + - ./my-config:/my-own-config-folder-injected +``` + +When the second steps runs, the `custom.txt` file is available both at `/codefresh/volume/my-config` (the shared volume of all steps) as well as the `/my-own-config-folder-injected` folder which was mounted specifically for this step. + + +## More freestyle steps + +You can use in a freestyle step any Docker image available in a public repository such as Dockerhub. This makes the integration of Codefresh and various cloud tools very easy. + +Codefresh also offers a plugin directory at [http://codefresh.io/steps/](http://codefresh.io/steps/) created specifically for CI/CD operations. + +{% include +image.html +lightbox="true" +file="/images/pipeline/plugin-directory.png" +url="/images/pipeline/plugin-directory.png" +alt="Codefresh steps directory" +caption="Codefresh steps directory" +max-width="80%" +%} + + +## What to read next + +* [Introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline Steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) + diff --git a/_docs/pipelines/steps/git-clone.md b/_docs/pipelines/steps/git-clone.md new file mode 100644 index 00000000..fa1e4084 --- /dev/null +++ b/_docs/pipelines/steps/git-clone.md @@ -0,0 +1,438 @@ +--- +title: "Git-Clone" +description: "Checkout code in your pipelines" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/git-clone/ +toc: true +--- +Clones a Git repository to the filesystem. + +A pipeline can have any number of git clone steps (even none). You can checkout code from any private or public repository. Cloning a repository is not constrained to the trigger of a pipeline. You can trigger a pipeline from a commit that happened on Git repository A while the pipeline is checking out code from Git Repository B. + +>Notice that if you are an existing customer before May 2019, Codefresh will automatically checkout the code from a [connected git repository]({{site.baseurl}}/docs/integrations/git-providers/) when a pipeline is created on that repository. In this case an implicit git clone step is included in your pipeline. You can still override it with your own git clone step as explained in this page + +## Usage + + `YAML` +{% highlight yaml %} +step_name: + type: git-clone + title: Step Title + description: Step description + working_directory: /path + repo: owner/repo + git: my-git-provider + revision: abcdef12345' + use_proxy: false + credentials: + username: user + password: credentials + fail_fast: false + when: + branch: + ignore: [ develop ] + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `working_directory` | The directory to which the repository is cloned. It can be an explicit path in the container's file system, or a variable that references another step. The default value is {% raw %}`${{main_clone}}`{% endraw %}, but note that the default will only be used if you name your step `main_clone`. See the example on [working inside the cloned directory]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/#working-inside-the-cloned-directory) for more information. | Default | +| `git` | The name of the [git integration]({{site.baseurl}}/docs/integrations/git-providers/) you want to use. If left empty, Codefresh will attempt to use the git provider that was used during account sign-up. Note that this might have unexpected results if you are changing your Git integrations.| Required| +| `repo` | path of the repository without the domain name in the form of `my_username/my_repo` | Required | +| `revision` | The revision of the repository you are checking out. It can be a revision hash or a branch name. The default value is the branch you have specified in your Git provider (e.g `master` or `main`). | Default | +| `use_proxy` | If set to true the Git clone process will honor `HTTP_PROXY` and `HTTPS_PROXY` variables if present for [working via a proxy](#using-git-behind-a-proxy). Default value is `false`. | Default | +| `credentials` | Credentials to access the repository, if it requires authentication. It can an object containing `username` and `password` fields. Credentials are optional if you are using the [built-in git integrations]({{site.baseurl}}/docs/integrations/git-providers/) . | Optional | +| `fail_fast` | If a step fails and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +**Exported resources:** +- Working Directory + +{{site.data.callout.callout_info}} +If you want to extend the git-clone step you can use the freestyle step. Example how to do it you can find [here]({{site.baseurl}}/docs/yaml-examples/examples/git-clone-private-repository-using-freestyle-step/) +{{site.data.callout.end}} + +## Basic clone step (project-based pipeline) + +The easiest way to use a git clone step is to use your default git provider as configured in [built-in git integrations]({{site.baseurl}}/docs/integrations/git-providers/). + +Here is an example of a pipeline that will automatically check out the repository that triggered it (i.e. a commit happened on that repository). + +>Notice that the name of the clone step is `main_clone`. This will automatically set the working directory of all other steps that follow it **inside** the folder of the project that was checked out. This only applies to [built-in]({{site.baseurl}}/docs/codefresh-yaml/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/codefresh-yaml/steps/#creating-a-typed-codefresh-plugin). This is normally what you want for a pipeline that only checks out a single project. If you use any other name apart from `main_clone` the working directory for all subsequent steps will not be affected and it will default on the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) which is the [parent folder]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) of checkouts. + + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + git: my-git-provider + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +The CF values will be automatically filled by Codefresh from the git trigger. See the [variables page]({{site.baseurl}}/docs/codefresh-yaml/variables/) for more details. + +## Choosing a specific git provider (project-based pipeline) + +If you don't want to use the default git provider you can explicitly set the provider by using the same name of the integration as it is shown in [the git integrations page]({{site.baseurl}}/docs/integrations/git-providers/). + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/example-git-providers.png" +url="/images/codefresh-yaml/steps/example-git-providers.png" +alt="Example git integrations" +caption="Example git integrations" +max-width="40%" +%} + +Here is an example for an integration with the GitLab provider already connected: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + git: my-gitlab + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +## Checkout a specific repository/revision (project based pipeline) + +If you want to check out a specific git repository regardless of what repository actually created the trigger +you can just define all values in a non-static manner. For example, if you want your pipeline to always checkout git repository `foo` even when the trigger happened from repository `bar` you can define the checkout step as below: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: 'my-github-username/foo' + revision: '${{CF_REVISION}}' + git: my-github-integration + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +In a similar manner you can also define that the pipeline will always checkout master, regardless of the commit that actually triggered it. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: 'master' + git: my-git-provider + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +## Checkout code using the Codefresh Runner + +If you are using the [Hybrid version]({{site.baseurl}}/docs/enterprise/installation-security/#hybrid-installation) of Codefresh and a have a [Codefresh runner]({{site.baseurl}}/docs/enterprise/codefresh-runner/) installed, you need to use +the fully qualified path of the git repository: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: https://github-internal.example.com/my-username/my-app + revision: '${{CF_REVISION}}' + git: my-internal-git-provider + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +More details can be found in the [private Git instructions page]({{site.baseurl}}/docs/enterprise/behind-the-firewall/#checking-out-code-from-a-private-git-repository). + + +## Checking multiple git repositories + +It is very easy to checkout additional repositories in a single pipeline by adding more `git-clone` steps. +In that case you should use different names for the steps (instead of `main_clone`) as this will make the working +folder for all steps the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps). + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + my_first_checkout: + title: 'Cloning first repository...' + type: git-clone + repo: 'my-gitlab-username/foo' + revision: '${{CF_REVISION}}' + git: my-gitlab-integration + my_second_checkout: + title: 'Cloning second repository...' + type: git-clone + repo: 'my-github-username/bar' + revision: '${{CF_REVISION}}' + git: my-github-integration + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + + +## Skip or customize default clone (repository-based pipeline) + +If you have existing pipelines connected to repositories (only for Codefresh accounts created before May 2019) +a git clone step is transparently added to git attached pipelines without you having to explicitly add a step into the pipeline. This is a convenience to enable easy CI pipelines. +If you do not require git cloning, or you would like to customize the implicit git cloning behavior, you can choose to skip the automatically added git clone step. + +There are 2 ways to do that: + +1. Add a pipeline environment variable called `CF_SKIP_MAIN_CLONE` with value of `true`. + +-or- + +2. Add a step with key `main_clone` to your pipeline. This step can be of any type and can do any action. This step will override the default clone implementation. for example: + +```yaml +version: '1.0' +steps: + main_clone: + title: Checking out code + image: alpine/git:latest + commands: + - git clone ... + another_step: + ... +``` + +## Reuse a Git token from Codefresh integrations + +You also have the capability to use one of your existing [git integrations]({{site.baseurl}}/docs/integrations/git-providers/) +as an authentication mechanism. + +The [Codefresh CLI](https://codefresh-io.github.io/cli/) can read one of the connected [git authentication contexts](https://codefresh-io.github.io/cli/contexts/get-context/) and use that token for a custom clone step. + +Here is an example for GitHub + + +```yaml +version: '1.0' +steps: + get_git_token: + title: Reading GitHub token + image: codefresh/cli + commands: + - cf_export GITHUB_TOKEN=$(codefresh get context github --decrypt -o yaml | yq -r .spec.data.auth.password) + main_clone: + title: Checking out code + image: alpine/git:latest + commands: + - git clone https://my-github-username:$GITHUB_TOKEN@github.com/my-github-username/my-repo.git + another_step: + ... +``` + +## Working with GIT submodules + +To checkout a git project including its submodules you can use the [Codefresh submodule plugin](https://github.com/codefresh-io/plugins/tree/master/plugins/gitsubmodules). This plugin is already offered as a public docker image at [Dockerhub](https://hub.docker.com/r/codefresh/cfstep-gitsubmodules/tags). + +To use this module in your pipeline, add a new step like the one shown below. + +```yaml +version: '1.0' +steps: + updateSubmodules: + image: codefresh/cfstep-gitsubmodules + environment: + - GITHUB_TOKEN= + - CF_SUBMODULE_SYNC= + - CF_SUBMODULE_UPDATE_RECURSIVE= +``` + +The GitHub token can be either defined in the pipeline on its own as an environment variable, or fetched from +the existing [GIT integration]({{site.baseurl}}/docs/integrations/git-providers/) as shown in the previous section. + +Here is full pipeline example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - prepare + - build +steps: + clone: + title: Cloning the repository + type: git-clone + stage: checkout + arguments: + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + git: github + revision: '${{CF_REVISION}}' + + updateSubmodules: + image: codefresh/cfstep-gitsubmodules + stage: prepare + working_directory: '${{clone}}' + environment: + - GITHUB_TOKEN=${{MY_GITHUB_TOKEN}} + docker_build: + title: Building docker image + type: build + stage: build + working_directory: '${{clone}}/k8s/docker' + tag: current + disable_push: true + image_name: 'my-docker-image' + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the main source code +1. Updates submodules +1. Creates a docker image + + +## Use an SSH key with Git + +It is also possible to use an SSH key with git. When [creating your pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) add your SSH key as an encrypted +environment variable after processing it with `tr`: + +``` +cat ~/.ssh/my_ssh_key_file | tr '\n' ',' +``` + + +Then in the pipeline use it like this: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Checking out code + image: alpine/git:latest + commands: + - mkdir -p ~/.ssh + - echo "${SSH_KEY}" | tr \'"${SPLIT_CHAR}"\' '\n' > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - git clone git@github.com:my-github-username/my-repo.git + # can also use go get or other similar command that uses git internally + another_step: + ... +{% endraw %} +{% endhighlight %} + +## Using Git behind a proxy + +If you use the [Codefresh Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) and need to use a network proxy in your clone step you need to set the [variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) `HTTP_PROXY` and/or `HTTPS_PROXY` in the pipeline +and then activate the property `use_proxy: true` in the clone step. Example: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "https://github.com/my-github-user/my-repo/" + revision: "master" + use_proxy: true + git: my-git-provider +{% endraw %} +{% endhighlight %} + +For setting the values of the proxy variables you can use any of the supported methods for defining variables such as [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/). + + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/steps/proxy-variables.png" +url="/images/codefresh-yaml/steps/proxy-variables.png" +alt="Pipeline variable" +caption="Pipeline variable" +max-width="40%" +%} + +For more details see the [behind the firewall page]({{site.baseurl}}/docs/administration/behind-the-firewall/). + + +## What to read next + +- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +- [Git integrations]({{site.baseurl}}/docs/integrations/git-providers/) +- [YAML steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +- [Git Checkout Examples]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) +- [Custom Git Commands]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout-custom/) + + + + + diff --git a/_docs/pipelines/steps/launch-composition.md b/_docs/pipelines/steps/launch-composition.md new file mode 100644 index 00000000..e2bd5d48 --- /dev/null +++ b/_docs/pipelines/steps/launch-composition.md @@ -0,0 +1,93 @@ +--- +title: "Launch-Composition" +description: "Create a test environment with its dependencies in Codefresh infrastructure" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/launch-composition-2/ + - /docs/codefresh-yaml/steps/launch-composition-2/ +toc: true +--- +The launch composition step provides the ability to launch long term running environments that can live outside the context of a running pipeline. +You can use this step to automate your test environment creation through a codefresh.yml file instead of manually launching an environment from the UI. + +>Note that "launch-composition" creates a permanent test environment that keeps running even after a pipeline has finished. If you just want temporary test environments that run *only while* a pipeline is running, see [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) and the documentation page for [integration tests]({{site.baseurl}}/docs/testing/integration-tests/). + +## Usage + + `ui defined composition` +{% highlight yaml %} +step_name: + title: Step Title + type: launch-composition + composition: 'ui_defined_composition_name' + environment_name: 'environment name' + on_success: + ... + on_fail: + ... + on_finish: + ... +{% endhighlight %} + + `inline composition` +{% highlight yaml %} +step_name: + type: launch-composition + composition: + version: '2' + services: + app: + image: owner/app:latest + db: + image: mongo + environment_name: 'environment name' + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... +{% endhighlight %} + + `from file composition` +{% highlight yaml %} +step_name: + type: launch-composition + working_directory: ${{a_clone_step}} + composition: './path/to/docker-compose.yaml' + environment_name: 'environment name' + on_success: + ... + on_fail: + ... + on_finish: + ... +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `working_directory` | The directory in which to search for the composition file. It can be an explicit path in the container's file system, or a variable that references another step.
The default is {% raw %}`${{main_clone}}`{% endraw %}. | Default | +| `composition` | The composition you want to run. It can be an inline YAML definition, a path to a composition file on the file system, or the logical name of a composition stored in the Codefresh system. | Required | +| `environment_name` | The environment name that will be given. In case a previous environment exists with the same name, it will first be terminated. The default value will the be the name/path provided in the 'composition' field. | Default | +| `composition_variables` | A set of environment variables to substitute in the composition. | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [[Conditional Execution of Steps]({{ site.baseurl }}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{ site.baseurl }}/docs/codefresh-yaml/post-step-operations/). | Optional | +| entry_point | The name of main service | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +## What to read next + +* [Preview environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) +* [Launch Composition example]({{site.baseurl}}/docs/yaml-examples/examples/launch-composition/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +* [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) \ No newline at end of file diff --git a/_docs/pipelines/steps/push.md b/_docs/pipelines/steps/push.md new file mode 100644 index 00000000..2f5356ea --- /dev/null +++ b/_docs/pipelines/steps/push.md @@ -0,0 +1,257 @@ +--- +title: "Push step" +description: "Pushing Docker images from your pipeline" +group: codefresh-yaml +sub_group: steps +redirect_from: + - /docs/push-1/ + - /docs/codefresh-yaml/steps/push-1/ +toc: true +--- + +{{site.data.callout.callout_info}} + +If you use only the default Docker registry of your account this step is optional as all successful Codefresh pipelines automatically push the Docker image they create in the default Docker registry. No further configuration is needed to achieve this behavior. +{{site.data.callout.end}} + +Push a built image to a remote Docker registry with one or more tags. Supports standard Docker registries and ECR. + +Notice that when you use [any external registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/), you need to comply to the naming pattern used by that registry, otherwise the build step will fail. For example, if your Codefresh image is tagged as `foo_username/my_image` but your Dockerhub account is `bar_username` then the build will fail and you need to customize the push step to use `bar_username` instead. This is a limitation of external registries such as Dockerhub. + +## Usage + + `YAML` +{% highlight yaml %} +step_name: + type: push + title: Step Title + description: Free text description + candidate: {% raw %}${{build_step_name}}{% endraw %} + tag: latest + image_name: codefresh/app + registry: my-registry + fail_fast: false + when: + branch: + only: + - /FB-/i + on_success: + ... + on_fail: + ... + on_finish: + ... + retry: + ... + +{% endhighlight %} + +## Fields + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `candidate` | The identifier of the image to push to the remote Docker registry. It can be an explicit identifier of an image to push, or a variable that references a `Build` step. | Required | +| `tag` | The tag under which to push the image. Use either this or `tags`.
The default is `latest`. | Default | +| `region` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The names of the regions for which to perform cross-region replication. The names of the source region and the destination region name must be defined in separate steps. | Optional | +| `role_arn` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The role with the required permissions to use to pull the image. For example, `arn:aws:iam:::role/` | Required | +| `aws_session_name` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The name of the AWS session. If not defined, `default-session-name` is used. | Default | +| `aws_duration_seconds` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The length of time, in seconds, for which the role credentials are considered valid, and must be between `900-3600` seconds. If not defined, the duration is set to the default of `3600` seconds. | Default | +| `tags` | Multiple tags under which to push the image. Use either this or `tag`. This is an array, so should be of the following style:
{::nomarkdown}
tags:
- tag1
- tag2
- {% raw %}${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}{% endraw %}
- tag4
{:/}or
{::nomarkdown}
tags: [ 'tag1', 'tag2', '{% raw %}${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}{% endraw %}', 'tag4' ]
{:/} | Default | +| `image_name` | The tagged image name that will be used The default value will be the same image name as of the candidate. | Default | +| `registry` | The registry logical name of one of the inserted registries from the integration view.
The default value will be your default registry [if you have more than one]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). | Default | +| `registry_context` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | + +## Examples + +Push an image to a registry connected with the [integration name]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) of `myazureregistry`. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- 'my build phase' +- 'my push phase' +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'my build phase' + type: build + image_name: my-app-image + dockerfile: Dockerfile + pushToMyRegistry: + stage: 'my push phase' + type: push + title: Pushing to a registry + candidate: ${{MyAppDockerImage}} + tag: ${{CF_SHORT_REVISION}} + registry: myazureregistry +{% endraw %} +{% endhighlight %} + +Push an image as the name of the branch in the [external registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) and also use a different image than the default. The same image will also by pushed as `latest` in the internal Codefresh registry (with the default name of `my-app-image`). + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- 'my build phase' +- 'my push phase' +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'my build phase' + type: build + image_name: my-app-image + dockerfile: Dockerfile + tag: latest + pushToMyRegistry: + stage: 'my push phase' + type: push + title: Pushing to a registry + candidate: ${{MyAppDockerImage}} + tag: ${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}} + registry: myazureregistry + image_name: my-user-name/a-different-image-name +{% endraw %} +{% endhighlight %} + + +Push an image with multiple tags. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- 'my build phase' +- 'my push phase' +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'my build phase' + type: build + image_name: my-app-image + dockerfile: Dockerfile + pushToMyRegistry: + stage: 'my push phase' + type: push + title: Pushing to a registry + candidate: ${{MyAppDockerImage}} + tags: + - ${{CF_SHORT_REVISION}} + - latest + - 2.0.0 + registry: myazureregistry +{% endraw %} +{% endhighlight %} + +Push an image with multiple tags to multiple Docker registries in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/). +Both registries are connected first in the [integrations page]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- 'my build phase' +- 'my push phase' +steps: + MyAppDockerImage: + title: Building Docker Image + stage: 'my build phase' + type: build + image_name: my-app-image + dockerfile: Dockerfile + PushingToRegistries: + type: parallel + stage: 'push' + steps: + PushingToGoogleRegistry: + type: push + title: Pushing To Google Registry + candidate: ${{MyAppDockerImage}} + tags: + - ${{CF_BUILD_ID}} + - latest + - production + registry: gcr + PushingToDockerRegistry: + type: push + title: Pushing To Dockerhub Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_SHORT_REVISION}}' + image_name: my-docker-hub-username/my-app-name + registry: dockerhub +{% endraw %} +{% endhighlight %} + + +## Using passed credentials without pre-saving them + +This option enables you to push your images without pre-saving the credentials in Codefresh's registry integration view. + +>Note that this method of pushing images is offered as a workaround. The suggested way is to use the [central Codefresh integration for registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) as explained in the previous section. + + `YAML` +{% highlight yaml %} +step_name: + type: push + title: Step Title + description: Free text description + candidate: {% raw %}${{build_step_name}}{% endraw %} + tags: [ latest, {% raw %}${{CF_BRANCH}}{% endraw %} ] + image_name: codefresh/app + registry: dtr.host.com + credentials: + username: subject + password: credentials + fail_fast: false + when: + branch: + only: + - /FB-/i + on_success: + ... + on_fail: + ... + on_finish: + ... +{% endhighlight %} + +{: .table .table-bordered .table-hover} +| Field | Description | Required/Optional/Default | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `provider` | The type of Docker registry provider. Can currently be either `docker` for a standard Docker registry, or `ecr` for the [Amazon EC2 Container Registry (ECR)](https://aws.amazon.com/ecr/). | Optional
*Default value*: `docker` | +| `candidate` | The identifier of the image to push to the remote Docker registry. It can be an explicit identifier of an image to push, or a variable that references a `Build` step. | Required | +| `tag` | The tag under which to push the image. Use either this or `tags`.
The default is `latest`. | Default | +| `tags` | Multiple tags under which to push the image. Use either this or 'tag'.
This is an array, so should be of the following style:
{::nomarkdown}
tags:
- tag1
- tag2
- {% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}
- tag4
{:/}or
{::nomarkdown}
tags: [ 'tag1', 'tag2', '{% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}', 'tag4' ]
{:/} | Default | +| `image_name` | The tagged image name that will be used. The default value will be the same image name as of the candidate. | Default | +| `registry` | The host address where the registry is located. The default is the registry configured in your Codefresh account, or Dockerhub. | Default
**Ignored when provider is** `ecr` | +| `credentials` | Credentials to access the registry if it requires authentication. It can be a has object containing `username` and `password` fields. The default is the credentials configured in your Codefresh account. | Optional
**Ignored when provider is** `ecr` | +| `accessKeyId` | Your AWS access key. | Optional
**Ignored when provider is** `docker` | +| `secretAccessKey` | Your AWS secret access key. | Optional
**Ignored when provider is** `docker` | +| `region` | The region where the ECR registry is accessible. | Optional
**Ignored when provider is** `docker` | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | + +**Exported resources:** +- Image ID. + +## What to read next +- [External Registry integrations]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +- [Custom Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) +- [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) \ No newline at end of file diff --git a/_docs/pipelines/triggers.md b/_docs/pipelines/triggers.md new file mode 100644 index 00000000..ca732a38 --- /dev/null +++ b/_docs/pipelines/triggers.md @@ -0,0 +1,116 @@ +--- +title: "Pipeline Triggers" +description: "Choose when your pipelines should run" +group: configure-ci-cd-pipeline +redirect_from: + - /docs/pipeline-triggers/ + - /docs/pipeline-triggers/introduction-triggers/ +toc: true +--- + + +To create an effective CI/CD process, it should be possible to trigger a Codefresh pipeline execution not only on code repository events (like `push` or `PR`), but also on any "interesting" CD-related event, coming from some external system. + +Codefresh not only allows you to define different pipelines on a single project but it also offers you the capability to trigger them with completely separate mechanisms. + + +## Codefresh Trigger Types + +Trigger types currently supported by Codefresh are: + +* [Git Triggers](git-triggers) +* [Dockerhub Triggers](dockerhub-triggers) +* [Azure Registry Triggers](azure-triggers) +* [Quay Triggers](quay-triggers) +* [Helm Triggers](helm-triggers) +* [Artifactory Triggers](jfrog-triggers) +* [Cron Trigger](cron-triggers) +* [API/CLI Trigger]({{site.baseurl}}/docs/integrations/codefresh-api/) + +As an example, this project contains 4 pipelines: + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/pipeline-examples.png" +url="/images/pipeline/triggers/pipeline-examples.png" +alt="Sample pipelines" +caption="Sample pipelines" +max-width="70%" +%} + +Behind the scenes these pipelines are triggered from different events: + +* Pipeline "CI-build" is using a GIT trigger and starts after every commit to the code repository +* Pipeline "Sonarcloud" is executed every weekend using a cron (timed) trigger +* Pipeline "integration-test" is executed whenever a commit happens in a Pull request on the code +* Pipeline "deploy-prod-k8s" is executed whenever a Docker image is pushed to the Docker registry + +This is just an example. You are free to create your own triggers that match your own internal process. +It is also possible to add multiple triggers for a pipeline so that it is executed for more than one type of events. + +If a pipeline has no defined trigger you can still start it manually. + +For all trigger types you can also use the [Codefresh CLI](https://codefresh-io.github.io/cli/triggers/) to manage them. + + + +## Creating a new trigger for a pipeline + +By default, when you create a new project from a GIT provider it will start with a GIT trigger that runs on every commit. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/default-git-trigger.png" +url="/images/pipeline/triggers/default-git-trigger.png" +alt="Default GIT Trigger" +caption="Default GIT Trigger" +max-width="50%" +%} + +You can either delete this trigger, modify it, or add new ones. + +To add a new trigger, go to the *Triggers* tab in your pipeline editor and click the *Add Trigger* button. This will bring up the respective dialog where you are adding a new trigger. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +caption="Adding new Trigger dialog" +max-width="70%" +%} + +For more information see: + +* [Git Triggers](git-triggers) +* [Dockerhub Triggers](dockerhub-triggers) +* [Azure Registry Triggers](azure-triggers) +* [Quay Triggers](quay-triggers) +* [Helm Triggers](helm-triggers) +* [Artifactory Triggers](jfrog-triggers) +* [Cron Trigger](cron-triggers) + +## Disabling triggers + +You can easily disable a trigger manually if you don't want to be active anymore. +On the triggers tab click the gear icon on the top right (*Open advanced options*). + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/enable-triggers.png" +url="/images/pipeline/triggers/enable-triggers.png" +alt="Toggle a trigger on/off" +caption="Toggle a trigger on/off" +max-width="70%" +%} + + +Then click the toggle switch on each trigger that you want to enable/disable. You can later enable the same trigger again +by clicking the same switch. + +## What to read next + +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Git triggers](git-triggers) +* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) +* [Trigger a Kubernetes Deployment from a Dockerhub Push Event]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) diff --git a/_docs/pipelines/triggers/azure-triggers.md b/_docs/pipelines/triggers/azure-triggers.md new file mode 100644 index 00000000..f80f971c --- /dev/null +++ b/_docs/pipelines/triggers/azure-triggers.md @@ -0,0 +1,85 @@ +--- +title: "Azure Registry Trigger" +description: "Learn how to trigger Codefresh pipelines from Azure Registry events" +group: configure-ci-cd-pipeline +sub_group: triggers +redirect_from: + - /docs/pipeline-triggers/configure-azure-trigger/ +toc: true +--- + +It is possible to define and manage Azure Registry Pipeline triggers with the Codefresh UI. + +This allows you to trigger Codefresh pipelines when an Azure Registry event happens (e.g. a new Docker image is uploaded). + +## Manage Azure Triggers with Codefresh UI + + +The process involves two parts: + +1. Creating a trigger in Codefresh. This will result in a special Codefresh webhook URL +1. Creating a new notification in the Azure Registry that will use this URL to call Codefresh + +Make sure that you have an Azure cloud account and have already [created a registry](https://docs.microsoft.com/en-us/azure/container-registry/). + + +### Create a new Azure Trigger + +To add a new Azure trigger, navigate to a Codefresh Pipeline *Configuration* view and expand the *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="40%" +%} + +Fill the following information: + +* Registry Provider - select `Azure`. +* *Name of Registry* - put Azure name of registry (without `.azurecr.io`). +* *Image Repository Name* - Azure image repository name. +* *Action* - select `Push Image` action. +* *Tags* - optional filter to specify which image *tags* will trigger pipeline execution: [Re2](https://github.com/google/re2/wiki/Syntax) regular expression. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/azure/add-trigger-dialog.png" +url="/images/pipeline/triggers/azure/add-trigger-dialog.png" +alt="Azure Registry settings" +max-width="50%" +%} + +Click next and a new Dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/azure/view-trigger-dialog.png" +url="/images/pipeline/triggers/azure/view-trigger-dialog.png" +alt="Codefresh webhook URL" +max-width="50%" +%} + +Now we must set Azure to call this URL when an event takes place. + +### Setup Azure Notification + +The easiest way to create an Azure trigger is with the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/acr/webhook?view=azure-cli-latest#az-acr-webhook-create) (Also available in the Azure portal) + +Here is the command + +{% highlight shell %} +{% raw %} +az acr webhook create -n MyWebhook -r kostisregistry --uri "https://g.codefresh.io/nomios/azure?account=409f15bdd444&secret=7zyg5Zhb8xYBn4ms" --actions push delete +{% endraw %} +{% endhighlight %} + +The name can be anything you want. The URI is the Codefresh URL that was created in the previous step. + + +### Triggering a Codefresh pipeline with Azure push + +Now, every time you push a new Docker image to the selected Azure Docker repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Azure Push trigger event. + diff --git a/_docs/pipelines/triggers/cron-triggers.md b/_docs/pipelines/triggers/cron-triggers.md new file mode 100644 index 00000000..ad9cc13b --- /dev/null +++ b/_docs/pipelines/triggers/cron-triggers.md @@ -0,0 +1,104 @@ +--- +title: "Cron Trigger" +description: "Run pipelines with a time schedule" +group: configure-ci-cd-pipeline +sub_group: triggers +redirect_from: + - /docs/configure-cron-trigger/ + - /docs/pipeline-triggers/configure-cron-trigger/ +toc: true +--- + +Cron triggers allow you to create pipelines that start on a specific time schedule. This is very useful for cleanup jobs or periodic checks or any other workflow that needs to run after a time interval. + +>All times mentioned in Cron triggers are using the UTC time zone. + +## Manage Cron Triggers with Codefresh UI + +It is possible to define and manage Cron-based pipeline triggers with Codefresh UI. + +### Create a new Cron Trigger + +To add a new Cron trigger, navigate to Codefresh Pipeline *Configuration* view and expand *Triggers* section. Press the `Add Trigger` button and select a `Cron` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="60%" +%} + + +Visit [this page](https://github.com/codefresh-io/cronus/blob/master/docs/expression.md) to learn about supported `cron` expression format and aliases. + + +Fill the following information: + +* Use Cron helper wizard to build a valid `cron` expression or write custom `cron` expression on the last tab. +* Add a free text message, that will be sent as an additional event payload every time `cron` is executed. + +{% include image.html +lightbox="true" +file="/images/cron_trigger.png" +url="/images/cron_trigger.png" +alt="Add Cron Trigger" +max-width="70%" +%} + + +### Triggering Codefresh pipeline with cron timer + +Now, `cron` will trigger a recurrent pipeline execution based on the defined `cron expression`. + +## Manage Cron Triggers with Codefresh CLI + +It is also possible to use the Codefresh Command Line client (`CLI`) to manage Cron based pipeline triggers. + +### Cron Trigger + +It is possible to trigger a Codefresh CD pipeline(s) periodically, using `cron` expression. + +You can use [Codefresh CLI](https://cli.codefresh.io/) to setup a Codefresh `cron` trigger. + +#### Create Cron trigger-event + +First, you need to create a new `cron` `trigger-event` to define a recurrent event. + +```sh +# create DockerHub recurrent event 'once in 20 minutes' +codefresh create trigger-event --type cron --kind codefresh --value expression="0 */20 * * * *" --value message="hello-once-in-20-min" + +# on success trigger-event UID will be printed out +Trigger event: "cron:codefresh:codefresh:0 */20 * * * *:hello-once-in-20-min:107e9db97062" was successfully created. +``` + +When creating a `cron trigger-event`, it is possible to specify a short text message, that will be passed to linked pipelines, every time the specified `cron` timer is triggered. + +Visit [this page](https://github.com/codefresh-io/cronus/blob/master/docs/expression.md) to learn about the supported `cron` expression format and aliases. + +#### Setup pipeline trigger + +Now, lets create a new pipeline trigger, linking previously defined `cron` `trigger-event` to one or more Codefresh pipelines. + +```sh +# create trigger, linking trigger-event UID to the pipeline UID +codefresh create trigger "cron:codefresh:codefresh:0 */20 * * * *:hello-once-in-20-min:107e9db97062" 7a5622e4b1ad5ba0018a3c9c + +# create another trigger, linking the same trigger-event to another pipeline +codefresh create trigger "cron:codefresh:codefresh:0 */20 * * * *:hello-once-in-20-min:107e9db97062" 4a5634e4b2cd6baf021a3c0a +``` + +From now on, every 20 minutes Codefresh will trigger a pipeline execution for 2 pipelines linked to the previously specified `cron` `trigger-event` (once in 20 minutes) + +#### Cron Event payload + +The following variables will be available for any Codefresh pipeline linked to a `cron` `trigger-event`: + +- `EVENT_MESSAGE` - free text message (specified during creation) +- `EVENT_TIMESTAMP` - event timestamp in RFC 3339 format + +## What to read next +- [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) +- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) + diff --git a/_docs/pipelines/triggers/dockerhub-triggers.md b/_docs/pipelines/triggers/dockerhub-triggers.md new file mode 100644 index 00000000..71dda94a --- /dev/null +++ b/_docs/pipelines/triggers/dockerhub-triggers.md @@ -0,0 +1,149 @@ +--- +title: "DockerHub Trigger" +description: "" +group: configure-ci-cd-pipeline +sub_group: triggers +redirect_from: + - /docs/configure-dockerhub-trigger/ + - /docs/pipeline-triggers/configure-dockerhub-trigger/ +toc: true +--- + +## Manage DockerHub Triggers with Codefresh UI + +It is possible to define and manage DockerHub pipeline triggers with Codefresh UI. + +### Create a new DockerHub Trigger + +To add a new DockerHub trigger, navigate to Codefresh Pipeline *Configuration* view and expand *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="60%" +%} + +Fill the following information: + +* *Registry Provider* - select `DockerHub`. +* *User/Organization Name* - put DockerHub user name or organization name here. +* *Image Repository Name* - DockerHub image repository name. +* *Action* - select `Push Image` action. +* *Tag* - optional filter to specify which image *tags* will trigger pipeline execution: [Re2](https://github.com/google/re2/wiki/Syntax) regular expression. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/dockerhub/dockerhub_trigger_1.png" +url="/images/pipeline/triggers/dockerhub/dockerhub_trigger_1.png" +alt="Add Registry Trigger" +max-width="70%" +%} + +### Setup DockerHub Webhook + +Currently Codefresh does not support to automatically setup a DockerHub webhook. You need to do this manually. Press the *Next* button and see detailed instructions with URL links and secrets of how-to setup a DockerHub Webhook. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/dockerhub/dockerhub_trigger_2.png" +url="/images/pipeline/triggers/dockerhub/dockerhub_trigger_2.png" +alt="Add Webhook" +max-width="70%" +%} + +1. Copy `Endpoint` URL +1. Visit DockerHub image settings page following link in help +1. Add a new DockerHub Webhook with previously copied `Endpoint` URL + +### Triggering Codefresh pipeline with DockerHub push + +Now, every time you push a new Docker image to selected DockerHub repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with this DockerHub Push trigger event. + +## Manage DockerHub Triggers with Codefresh CLI + +It is possible to use `codefresh` command line client (`CLI`) to manage DockerHub pipeline triggers. + +### Docker Hub Trigger + +It is possible to trigger a Codefresh CD pipeline(s) when a new Docker image pushed into DockerHub. + +You can use [Codefresh CLI](https://cli.codefresh.io/) to setup a Codefresh trigger for DockerHub. + +#### Create DockerHub trigger-event + +First, create a `trigger-event` for every DockerHub image, you would like to setup a Codefresh trigger. + +```sh +# create DockerHub trigger event for codefresh/fortune +codefresh create trigger-event --type registry --kind dockerhub --value namespace=codefresh --value name=fortune --value action=push + +# on success trigger-event UID will be printed out +Trigger event: registry:dockerhub:codefresh:fortune:push:107e9db97062 was successfully created. +``` + +#### Setup DockerHub Webhook + +Currently, an additional manual work is required to bind DockerHub `push` image event to the Codefresh `trigger-event`. + +```sh +# get trigger-event details for previously created trigger-event +codefresh get trigger-event -o yaml registry:dockerhub:codefresh:fortune:push:107e9db97062 +``` + +... command output: + +```yaml +uri: 'registry:dockerhub:codefresh:fortune:push:107e9db97062' +type: registry +kind: dockerhub +public: false +secret: aGao5weuez2G6WF9 +status: active +endpoint: >- + https://g.codefresh.io/nomios/dockerhub?account=107e9db97062&secret=aGao5weuez2G6WF9 +description: Docker Hub codefresh/fortune push event +help: >- + Docker Hub webhooks fire when an image is built in, pushed or a new tag is + added to, your repository. + + + Configure Docker Hub webhooks on + https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/ + + + Add following Codefresh Docker Hub webhook endpoint + https://g.codefresh.io/nomios/dockerhub?account=107e9db97062&secret=aGao5weuez2G6WF9 +``` + +1. Copy `endpoint` URL +1. Visit DockerHub settings page [https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/](https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/) +1. Add a new Webhook with previously copied `endpoint` URL + + +#### Setup pipeline trigger + +Now, lets setup a new pipeline trigger, linking previously defined DockerHub push `codefresh/fortune` `trigger-event` to one ore more Codefresh pipelines. + +```sh +# create trigger, linking trigger-event UID to the pipeline UID +codefresh create trigger "registry:dockerhub:codefresh:fortune:push:107e9db97062" 7a5622e4b1ad5ba0018a3c9c + +# create another trigger, linking the same trigger-event to another pipeline +codefresh create trigger "registry:dockerhub:codefresh:fortune:push:107e9db97062" 4a5634e4b2cd6baf021a3c0a +``` + +From now on, Codefresh will trigger pipeline execution when new `codefresh/fortune` image is pushed to the DockerHub. + +#### DockerHub Event payload + +The following variables will be available for any Codefresh pipeline linked to a DockerHub `trigger-event`: + +- `EVENT_NAMESPACE` - DockerHub namespace (alias `organization`). +- `EVENT_NAME` - DockerHub image name (alias `repository`). +- `EVENT_TAG` - Docker image tag. +- `EVENT_PUSHER` - user who pushed this Docker image. +- `EVENT_PUSHED_AT` - timestamp for push event. +- `EVENT_PAYLOAD` - original DockerHub Webhook JSON payload. diff --git a/_docs/pipelines/triggers/git-triggers.md b/_docs/pipelines/triggers/git-triggers.md new file mode 100644 index 00000000..81981056 --- /dev/null +++ b/_docs/pipelines/triggers/git-triggers.md @@ -0,0 +1,365 @@ +--- +title: "Git Triggers" +description: "Learn how to run pipelines from Git events" +group: configure-ci-cd-pipeline +sub_group: triggers +toc: true +--- + +GIT triggers are the most basic types of trigger for performing [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) with Codefresh. + +At the trigger level you have the option of selecting: + +* Which code repository will be used as a trigger +* Which branches will be affected by a pipeline +* If a trigger will apply to a Pull Request or not + + Note that you can select another repository other than the one the project itself belongs to. It is possible + to trigger a build on project A even though a commit happened on project B. + +You can also use [Conditional expressions]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) at the pipeline level to further fine-tune the way specific steps (or other transitive pipelines) are executed. + +## Manage GIT Triggers with Codefresh UI + +To add a new GIT trigger, navigate to the Codefresh Pipeline *Configuration* view and expand the *Triggers* section on the right side. Press the *Add Trigger* button and select a *GIT* trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="60%" +%} + +## General Trigger Settings + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-git-trigger.png" +url="/images/pipeline/triggers/add-git-trigger.png" +alt="Adding GIT Trigger" +max-width="50%" +%} + +The Git Trigger is comprised of the following settings: + +* *Trigger Name* - a freetext trigger name (required). +* *Description* - a freetext description (optional). +* *Repository* - you can select any repository even something different than the one that is used for the code checkout. +* *Commit Checkbox* - if enabled will trigger this pipeline for any commit. +* *PR Checkboxes* - various checkboxes for filtering the Pull request event. + +The commit checkbox (by default it is enabled) means that this pipeline will run for *any* commit as long as its source branch matches the naming scheme. This includes commits on pull requests. + +The PR checkboxes mean that this pipeline will run only on the respective events that happen on a Pull Request. You can select multiple checkboxes to further fine-tune the exact event. If you are interested in all events, select the checkbox *Any Pull Request event*. + +>The individual Pull request checkboxes are available only for GitHub repositories. + +## Configure Filter Settings + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/configure-filter-settings.png" +url="/images/pipeline/triggers/configure-filter-settings.png" +alt="Configure Filter Settings" +max-width="50%" +%} + +* *Support pull request events from forks* - toggle that is useful for open source projects. +* *Branch Field* - this is a regular expression and will only trigger for branches that match this naming pattern. +* *PR Comment (restricted) and PR Comment Fields* - useful for open source projects. +* *Pull Request Target* branch - this is a regular expression and will trigger only when a Pull request is created against any branch that matches it. +* *Modified Files* - allows you to constrain the build and trigger it only if the modified files from the commit match this [glob expression](https://en.wikipedia.org/wiki/Glob_(programming)). + +### Pull Request Target Branch and Branch + +The Pull Request Target Branch field allows you to trigger this pipeline only when the target of a Pull Request (i.e. where the pr is going to be merged at) matches the +branch name regular expression. Common examples for branch names would be `master` or `production`. + +This field has only meaning when a commit happens in the context of a pull request and in that case: + +1. The Branch field will look at the branch that the commit is happening on +1. The PR Target Branch field will look at the branch the PR is happening against + +For example, if you create a commit on a branch that is named `my-feature` which is currently part of PR against branch `staging` (i.e. somebody wants to merge `my-feature` **TO** `staging`) then: + +1. The `BRANCH` field value will try to match against `my-feature` +1. the `PULL REQUEST TARGET BRANCH` will try to match against `staging` + +Here are some more syntax examples: + +* `/^((qa-release)$).*/g` - only run if branch is named `qa-release`. +* `/^((production)$).*/g` - only run if branch is named `production`. +* `/release/g` - only run if branch name contains `release` as substring. +* `/feature-/gi` - only run if branch is `feature-foo`, `feature-bar`, `my-feature-123` etc. +* `/^((?!^feature).)*$/gi` - only run if branch name does **not** start with `feature`. + +>The field *Pull Request Target* is available for all Git providers apart from Atlassian stash. +> +>When using the Terraform Provider, please use the [Go regex syntax](https://github.com/google/re2/wiki/Syntax) as some perl regex syntax is not compatible. + +The concept behind these checkboxes and branch name fields is to allow you to define which pipelines run for various workflows in your organization. + +As a simple example you can have a *production* pipeline that runs only on *master* branch (and therefore the branch field says "master") and a *testing* pipeline that runs user acceptance tests where only the Pull Request Open checkbox is active. This means that User Acceptance tests will run whenever a PR is created. Once it is merged the *production* pipeline will deploy the changes. + +In a more advanced example, you could add regular expressions in the branch field with names such as *feature-*, *hotfix-* etc. and the PR checkbox active on different pipelines. This way you could trigger the pull requests only when they happen on specific branches. So, a developer that creates a temporary feature with a name that doesn't match these naming patterns will not trigger those pipelines. + +Notice also that you can use Negative Lookahead in your Branch (Regex Expression) filter. An example to exclude tag events: `/^((?!tag)).*/gi` (the pattern here for tags to exclude is that they begin with `tag…`). + +This will make all push-events (including tags) that do follow the `tag...` pattern to be excluded. +Therefore, all tags like `tag1`, `tag-X` **won't** trigger the pipeline. + +### Pull Requests from comments + +Pull Requests from comments are supported for all Git providers, for private and public repositories. +There are two options: +* **Pull request comment added (restricted)** + This option triggers an event only when the PR comments are made by repository owners or collaborators. +* **Pull request comment added** + This option triggers an event when PR comments are made by any user, regardless of their permissions. + Because it is not restricted to owners and collaborators, this option is useful in GitHub, to enable triggers for PR comments made by users in GitHub teams. + + > We strongly recommend selecting this option only for _private repositories_. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/pr-comment-trigger-options.png" +url="/images/pipeline/triggers/pr-comment-trigger-options.png" +alt="Trigger options for PR comments" +caption="Trigger options for PR comments" +max-width="50%" +%} + + +### Support for building pull requests from forks + +By default, the Git trigger works for events coming from your personal repository. You can also use triggers from events that are coming from forks. This is a very useful feature for open source projects, as it allows you to run your own unit tests and other checks against a new feature *before* actually merging it in your repo. + +To enable this behavior: + +* Toggle the *support pull request events from forks* switch +* Select *Pull request comment added (restricted)* +* In the *pr comment* field enter a custom string (accepts regex) + +Then once a contributor creates a fork of your repository and submits a pull request, you can review the code and then add a comment on your own that matches the PR comment expression. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/pr-from-fork.png" +url="/images/pipeline/triggers/pr-from-fork.png" +alt="Triggering a public build from a comment" +caption="Triggering a public build from a comment" +max-width="50%" +%} + +Once that is done, Codefresh will launch your pipeline against the Pull Request. If you manage an open source project with Codefresh, remember to enable [public builds]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/#public-build-logs) as well. + +When supporting building of pull requests from forks there are a few "gotchas" to look out for: + +* Only comments made by repository owners and [collaborators](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/adding-outside-collaborators-to-repositories-in-your-organization) will result in the pipeline being triggered. +* Only git pushes by collaborators within the GitHub organization will result in the pipeline being triggered +* If the repository is in a GitHub organization, comments made by private members of the organization will not activate the trigger, even if they are set as an owner or collaborator. Private members means that they need to be explicitly added to the repository. +Access cannot be "inherited" by the GitHub team. Currently, only comments from Admins, or Collaborators (directly added, not via teams) are allowed, in order to be caught by this filter. +* The *Pull request comment added* checkbox should likely be the only one checked, or your pipeline may trigger on other events that you don't anticipate. + + + +### Monorepo support (Modified files) + +The *modified files* field is a very powerful Codefresh feature that allows you to trigger a build only if the +files affected by a commit are in a specific folder (or match a specific naming pattern). This means that +you can have a big GIT repository with multiple projects and build only the parts that actually change. + +>Currently the field *modified files* is available only for GitHub, GitLab, Azure DevOps and [Bitbucket Server and Data Center](https://confluence.atlassian.com/bitbucketserver/add-a-post-service-webhook-776640367.html) repositories, since they are the only GIT providers +that send this information in the webhook. We will support other GIT providers as soon as they add the respective feature. + +### Using the Modified files field to constrain triggers to specific folder/files + +The *modified files* field accepts glob expressions. The paths are relative to the root folder of the project (where the git repository was checked out). Some possible examples are: + +``` +**/package.json +**/Dockerfile* +my-subproject/** +my-subproject/sub-subproject/package.json +my-subproject/**/pom.xml +!config/** + +``` + +>You can also use relative paths with dot-slash. Therefore `./package.json` and `package.json` are exactly the same thing. They both refer to the file `package.json` found at the root of the git project that was checked out as part of the build. + +You can also define [multiple expressions](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm) like this (but notice that there is a limit of 150 characters for the field): + +``` +{app/**,test/**} +{**/package.json,my-subproject/**} +!{deployment/**,**/version.cfg} +``` + +Once a commit happens to a code repository, Codefresh will see which files are changed from the git provider and trigger the build **only** if the changed files match the glob expression. If there is no match no build will be triggered. + +> Notice that the `{}` characters are only needed if you have more than one expression. Do not use them if you have a single glob expression in the field. + +This is a very useful feature for organizations who have chosen to have multiple projects on the same GIT repository (monorepos). Let's assume for example that a single system has a Java backend, a NestJS frontend and a Ruby-on-Rails internal dashboard. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/monorepo.png" +url="/images/pipeline/triggers/monorepo.png" +alt="GIT monorepo" +max-width="60%" +%} + +Now we can define 3 different pipelines in Codefresh where each one builds the respective project + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/monorepo-pipelines.png" +url="/images/pipeline/triggers/monorepo-pipelines.png" +alt="GIT monorepo pipelines" +max-width="70%" +%} + +And then in the GIT trigger for each one we set the modified files field to the following values: + +* For the *build-nestjs-only* pipeline *MODIFIED FILES* has `my-nestjs-project/**`. +* For the *build-java-only* pipeline *MODIFIED FILES* has `my-java-project/**`. +* For the *build-rails-only* pipeline *MODIFIED FILES* has `my-rails-project/**`. + +This way as multiple developers work on the git repository only the affected projects will actually build. A change to the NestJS project will *not* build the Rails project as well. Also, if somebody changes *only* the README file and nothing else, no build will be triggered at all (which is a good thing as the source code is exactly the same). + +You can also use Glob expressions for files. For example: + +* An expression such as `my-subproject/sub-subproject/package.json` will trigger a build **only** if the dependencies of this specific project are changed +* A pipeline with the expression `my-subproject/**/pom.xml` will trigger only if the Java dependencies for any project that belongs to `my-subproject` actually change +* An expression such as `!config/manifest.yaml` will trigger a build if any file was changed *apart from* `config/manifest.yaml` + +Glob expressions have many more options not shown here. Visit the [official documentation](https://en.wikipedia.org/wiki/Glob_(programming)) to learn more. You can also use the [Glob Tester web application](https://www.digitalocean.com/community/tools/glob) to test your glob expressions beforehand so that you are certain they match the files you expect them to match. + +## Advanced Options + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/advanced-options.png" +url="/images/pipeline/triggers/advanced-options.png" +alt="Advanced Options" +max-width="60%" +%} + +* *Commit Status Title* - the commit status title pushed to the GIT version control system. By default, is the pipeline name, but you can override the name on GIT trigger. +* *Build Variables* - import a [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) or manually add variables +* *More Options* + * *Ignore Docker engine cache for build* - selecting this option may slow down your build. See #1 [here]({{site.baseurl}}/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) + * *Ignore Codefresh cache optimizations for build* - selecting this option may slow down your build. See #2 [here]({{site.baseurl}}/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) + * *Reset pipeline volume* - useful for troubleshooting a build that hangs on the first step. See [here]({{site.baseurl}}/docs/troubleshooting/common-issues/restoring-data-from-pre-existing-image-hangs-on/) + * *Report notification on pipeline execution* - Decide if [Slack notifications]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) will be sent (as well as status updates back to your Git provider) +* *Runtime Environment* - choose to use pipeline [settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) or override them + +## Manually Adding the Trigger to GitHub + +When creating a Git Trigger in codefresh, sometimes the Git Integration does not have the permissions to create a webhook on the designated repository. When this happens, you get the following error: `Failed to add Trigger`. + +This error means that Codefresh could not create the webhook and verify that it works. With that, Codefresh will mark the Trigger as Unverified. Two additional fields (Endpoint and Secret) will appear under the "Verify Trigger" button when you get this error. + +- **Endpoint**: This will be the Webhook URL for the created Trigger +- **Secret**: Token to add to Github for verification. + +### Adding Webhook to Github + +1. When you receive the `Failed to add Trigger`. +2. Log into GitHub + - Make this user can access the repository settings and create Webhooks +3. Go to the repository mentioned in the "REPOSITORY" section from Unverified Trigger. +4. Go to Settings > Webhooks and click the "Add webhook" button. +5. Fill in the form + - **Payload URL**: The URL from the Endpoint field from the Trigger + - **Content type**: application/json + - **Secret**: The token in the Secret field from the Trigger + - **SSL verification**: Enable SSL verification + - **Events**: + 1. Select let me select individual events + 2. Match the items selected in the Trigger By field from the Trigger + - **Active**: Make sure this is selected +6. Click "Add webhook" when done. +7. Click "Done" in the Add Trigger form. +8. Test your webhook by making an event in the repository that will cause the Trigger to start the build. + +> **Note**: +> +> - You will be responsible for syncing the Trigger By to the Events sent to us for the webhook. You can select "Send me everything" if you do not want to manually match the Trigger By in the Trigger with the Webhook Events in GitHub. +> - The Trigger will remain "Unverified" until the integration has the correct permissions to the repository. + +## Accessing directly the webhook content of the trigger + +If your Git trigger is coming from Github, you can also access the whole payload of the webhook that was responsible for the trigger. +The webhook content is available at `/codefresh/volume/event.json`. You can read this file in any pipeline step and process it like any other json file (e.g. with the jq utility). + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + read_trigger_webook: + title: "Reading Github webhook content" + type: "freestyle" + image: "alpine:3.9" + commands: + - 'cat /codefresh/volume/event.json' +{% endraw %} +{% endhighlight %} + +Notice however that this file is only available when the pipeline was triggered from a GitHub event. If you manually run the pipeline, the file is not present. + +## Using YAML and the Codefresh CLI to filter specific Webhook events + +The default GUI options exposed by Codefresh are just a starting point for GIT triggers and pull requests. Using [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) and the [Codefresh CLI plugin](https://codefresh-io.github.io/cli/) you can further create two-phase pipelines where the first one decides +which webhook events will be honored and the second one contains the actual build. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/two-phase-pipeline.png" +url="/images/pipeline/triggers/two-phase-pipeline.png" +alt="Two phase pipeline" +max-width="80%" +%} + +The generic GIT trigger is placed on Pipeline A. This pipeline then filters the applicable webhooks using [conditional expressions]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/). Then it uses the Codefresh CLI plugin (and specifically the [run pipeline capability](https://codefresh-io.github.io/cli/pipelines/run-pipeline/)) to trigger pipeline B that performs build. + +Some of the YAML variables that you might find useful (from the [full list]({{site.baseurl}}/docs/codefresh-yaml/variables/)): + +* `CF_PULL_REQUEST_ACTION` - open, close, synchronize, assign etc. +* `CF_PULL_REQUEST_TARGET` - target branch of the pull request. +* `CF_BRANCH` - the branch that contains the pull request. + +As an example, here is the `codefresh.yml` file of pipeline A where we want to run pipeline B only when a Pull Requested is opened against a branch named *production*. + +`codefresh.yml` of pipeline A +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + triggerstep: + title: trigger + image: codefresh/cli + commands: + - 'codefresh run -b=${{CF_BRANCH}}' -t + when: + condition: + all: + validateTargetBranch: '"${{CF_PULL_REQUEST_TARGET}}" == "production"' + validatePRAction: '''${{CF_PULL_REQUEST_ACTION}}'' == ''opened''' +{% endraw %} +{% endhighlight %} + +This is the build definition for the first pipeline that has a GIT trigger (with the Pull request checkbox enabled). +It has only a single step which uses conditionals that check the name of the branch where the pull request is targeted to, as well as the pull request action. Only if *both* of these conditions are true then the build step is executed. + +The build step calls the second pipeline. The end result is that pipeline B runs only when the Pull Request is opened the first time. Any further commits on the pull request branch will **not** trigger pipeline B (pipeline A will still run but the conditionals will fail). + +## What to read next + +* [Cron triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/cron-triggers/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Multi-git trigger]({{site.baseurl}}/docs/troubleshooting/common-issues/multi-git-triggers/) diff --git a/_docs/pipelines/triggers/helm-triggers.md b/_docs/pipelines/triggers/helm-triggers.md new file mode 100644 index 00000000..a2956373 --- /dev/null +++ b/_docs/pipelines/triggers/helm-triggers.md @@ -0,0 +1,62 @@ +--- +title: "Helm Trigger" +description: "" +group: configure-ci-cd-pipeline +sub_group: triggers +toc: true +--- + +Codefresh has the option to create pipelines that respond to Helm events. For instance, one pipeline can be set-up to create a Docker image and chart. Once those are created, another pipeline will be triggered that will take over the actual deployment. + +## Manage Helm Triggers with Codefresh UI + +It is possible to define and manage Helm pipeline triggers with the Codefresh UI. + +### Create a new Helm Trigger + +To add a new Helm trigger, navigate to Codefresh Pipeline *Configuration* view and expand *Triggers* section. Press the `Add Trigger` button and select the `Helm` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="60%" +%} + +Fill the following information: +* *Helm Provider* - select `JFrog Artifactory`. +* *Repository* - put JFrog name of the Artifactory repository. +* *Chart Name* - put name of the chart in the Artifactory repository. +* *Action* - select `Push Chart` action. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/jfrog/configure-artifactory.png" +url="/images/pipeline/triggers/jfrog/configure-artifactory.png" +alt="Helm Artifactory settings" +max-width="50%" +%} + +Click next and a new Dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/jfrog/view-trigger-dialog.png" +url="/images/pipeline/triggers/jfrog/view-trigger-dialog.png" +alt="Codefresh webhook URL" +max-width="50%" +%} + +Now we must set JFrog Artifactory to call this URL when an event takes place. This can either be done through the [JFrog Artifactory webhook plugin](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/jfrog-triggers/) or through [setting up Webhooks](https://www.jfrog.com/confluence/display/JFROG/Webhooks) in the UI. + +### Triggering a Codefresh pipeline with an Artifactory push + +Now, every time you push a Helm chart to the selected Artifactory repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Artifactory Push trigger event. + +## What to read next + +* [Git triggers](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/git-triggers/) +* [Helm Releases management](https://codefresh.io/docs/docs/new-helm/helm-releases-management/) +* [Custom Helm uploads](https://codefresh.io/docs/docs/new-helm/custom-helm-uploads/) \ No newline at end of file diff --git a/_docs/pipelines/triggers/jfrog-triggers.md b/_docs/pipelines/triggers/jfrog-triggers.md new file mode 100644 index 00000000..4a86b503 --- /dev/null +++ b/_docs/pipelines/triggers/jfrog-triggers.md @@ -0,0 +1,98 @@ +--- +title: "Artifactory Trigger" +description: "How to trigger Codefresh pipelines from Artifactory" +group: configure-ci-cd-pipeline +sub_group: triggers +redirect_from: + - /docs/pipeline-triggers/configure-jfrog-trigger/ +toc: true +--- + +It is possible to define and manage Artifactory pipeline triggers with the Codefresh UI. +This allows you to trigger Codefresh pipelines when a Artifactory event happens (i.e. a new Docker image is uploaded). + +## Manage Artifactory Triggers with Codefresh UI + + +The process involves two parts: + +1. Creating a trigger in Codefresh. This will result in a special Codefresh webhook URL +1. Activating the [webhook plugin](https://github.com/jfrog/artifactory-user-plugins/tree/master/webhook) in Artifactory and setting it up to call the Codefresh URL + +Make sure that you have admin access to your Artifactory instance in order to setup its webhook plugin. + +### Create a new Artifactory Trigger + +To add a new Artifactory trigger, navigate to a Codefresh Pipeline *Configuration* view and expand the *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="40%" +%} + +Fill the following information: + +* *Registry Provider* - select `JFrog`. +* *Repository Name* - put JFrog name of repository. +* *Docker Image Name* - put name of Docker image. +* *Action* - select `Push Image` action. +* *Tag* - optional filter to specify which image *tags* will trigger pipeline execution: [Re2](https://github.com/google/re2/wiki/Syntax) regular expression. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/jfrog/configure-trigger.png" +url="/images/pipeline/triggers/jfrog/configure-trigger.png" +alt="Artifactory Registry settings" +max-width="50%" +%} + +Click next and a new Dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/jfrog/view-trigger-dialog.png" +url="/images/pipeline/triggers/jfrog/view-trigger-dialog.png" +alt="Codefresh webhook URL" +max-width="50%" +%} + +Now we must set JFrog Artifactory to call this URL when an event takes place. + +### Setup JFrog Artifactory webhook plugin + +The [webhook functionality](https://github.com/jfrog/artifactory-user-plugins/tree/master/webhook) in JFrog artifactory comes in plugin. +You can read [detailed documentation](https://www.jfrog.com/confluence/display/RTF/User+Plugins) for JFrog plugins but in summary: + +* The file `webhook.groovy` needs to be copied to `ARTIFACTORY_HOME/etc/plugins` (the plugin itself) +* A file `webhook.config.json` should also be placed in the same folder (the plugin setup) + +Here is an example for Codefresh. + +`webhook.config.json` +{% highlight json %} +{% raw %} +{ + "webhooks": { + "mywebhook": { + "url": "https://g.codefresh.io/nomios/jfrog?account=2dfdf89f235bfe&sefgt=EvQf9bBS55UPekCu", + "events": [ + "docker.tagCreated" + ] + } + }, + "debug": false, + "timeout": 15000 +} +{% endraw %} +{% endhighlight %} + + + +### Triggering a Codefresh pipeline with an Artifactory push + +Now, every time you push/tag a Docker image to the selected Artifactory repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Artifactory Push trigger event. + diff --git a/_docs/pipelines/triggers/quay-triggers.md b/_docs/pipelines/triggers/quay-triggers.md new file mode 100644 index 00000000..682dec12 --- /dev/null +++ b/_docs/pipelines/triggers/quay-triggers.md @@ -0,0 +1,99 @@ +--- +title: "Quay Trigger" +description: "How to trigger Codefresh pipelines from Quay" +group: configure-ci-cd-pipeline +sub_group: triggers +redirect_from: + - /docs/pipeline-triggers/configure-quay-trigger/ +toc: true +--- + +It is possible to define and manage Quay pipeline triggers with the Codefresh UI. +This allows you to trigger Codefresh pipelines when a Quay event happens (e.g. a new Docker image is uploaded). + +## Manage Quay Triggers with Codefresh UI + + +The process involves two parts: + +1. Creating a trigger in Codefresh (this will result in a special Codefresh webhook URL) +1. Creating a new notification in Quay that will use this URL to call Codefresh + +Make sure that you have a Quay account and have already [created a repository](https://docs.quay.io/guides/create-repo.html) (or pushed a Docker image at least once). + + +### Create a new Quay Trigger + +To add a new Quay trigger, navigate to a Codefresh Pipeline *Configuration* view and expand the *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/add-trigger-dialog.png" +url="/images/pipeline/triggers/add-trigger-dialog.png" +alt="Adding new Trigger dialog" +max-width="40%" +%} + +Fill the following information: + +* *Registry Provider* - select `Quay`. +* *User/Organization Name* - put Quay username or organization name here. +* *Image Repository Name* - Quay image repository name. +* *Action* - select `Push Image` action. +* *Tag* - optional filter to specify which image *tags* will trigger pipeline execution: [Re2](https://github.com/google/re2/wiki/Syntax) regular expression. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/quay/add-trigger-dialog.png" +url="/images/pipeline/triggers/quay/add-trigger-dialog.png" +alt="Quay Registry settings" +max-width="50%" +%} + +Click next and a new Dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/quay/view-trigger-dialog.png" +url="/images/pipeline/triggers/quay/view-trigger-dialog.png" +alt="Codefresh webhook URL" +max-width="50%" +%} + +Now we must set Quay to call this URL when an event takes place. + +### Setup Quay Notification + +Log in your Quay account and go to the respective repository. You can also click the link shown in the Codefresh dialog to go directly to the settings of that repository. + +Scroll down and under *Events and Notifications* click *Create Notification*. + + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/quay/add-quay-notification.png" +url="/images/pipeline/triggers/quay/add-quay-notification.png" +alt="Add Quay Notification" +max-width="50%" +%} + +In the new screen select *Push to repository* from the drop-down or any other event that you wish the Codefresh pipeline to trigger. + +{% include image.html +lightbox="true" +file="/images/pipeline/triggers/quay/edit-quay-notification.png" +url="/images/pipeline/triggers/quay/edit-quay-notification.png" +alt="Edit Quay Notification" +max-width="50%" +%} + +From the next dropdown choose *Webhook Post*. In the *Webhook URL entry* paste the Codefresh URL that was created in the Codefresh Trigger dialog. + +Finally click *Create Notification*. + + +### Triggering a Codefresh pipeline with Quay push + +Now, every time you push a new Docker image to the selected Quay repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Quay Push trigger event. + diff --git a/_docs/pipelines/variables.md b/_docs/pipelines/variables.md new file mode 100644 index 00000000..5da55e75 --- /dev/null +++ b/_docs/pipelines/variables.md @@ -0,0 +1,340 @@ +--- +title: "Variables" +description: "" +group: codefresh-yaml +redirect_from: + - /docs/variables/ +toc: true +--- +Codefresh provides a set of predefined variables automatically in each build, that you can use to parameterize the way your pipeline works. You can also define your own variables. Some common examples of predefined variables include: + +* `CF_BRANCH` is the Git branch that was used for this pipeline. +* `CF_REVISION` is the Git hash that was used for this pipeline. +* `CF_BUILD_URL` is the url of the pipeline build. + +## Using Codefresh variables in your pipelines + +There are two ways to use a Codefresh variable in your pipelines: + +1. By default all variables will be exposed as UNIX environment variables in all freestyle steps as `$MY_VARIABLE_EXAMPLE`. +1. Variables can be used in YAML properties with the syntax {% raw %}`${{MY_VARIABLE_EXAMPLE}}`{% endraw %}. + +> If you are unsure about which form you need to use, feel free to use {% raw %}`${{MY_VARIABLE_EXAMPLE}}`{% endraw %} everywhere. This is the Codefresh specific form and should function in all sections of `codefresh.yml`. + +For example, you can print out the branch as an environment variable like this: + +`YAML` +{% highlight yaml %} +{% raw %} +MyOwnStep: + title: Variable example + image: alpine + commands: + - echo $CF_BUILD_ID + - echo $CF_BRANCH_TAG_NORMALIZED +{% endraw %} +{% endhighlight %} + +In the example above we are using simple `echo` commands, but any program or script that reads environment variables could also read them in the same manner. + +Using variables directly in yaml properties can be done like this: + +`YAML` +{% highlight yaml %} +{% raw %} +MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-own-app + tag: ${{CF_BRANCH_TAG_NORMALIZED}} +{% endraw %} +{% endhighlight %} + +You can also concatenate variables: + +`YAML` +{% highlight yaml %} +{% raw %} +MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-own-app + tag: ${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}} +{% endraw %} +{% endhighlight %} + +This will create docker images with tags such as: + +``` +master-df6a04c +develop-ba1cd68 +feature-vb145dh +``` + + + + +Notice that this syntax is specific to Codefresh and is **only** available within the Codefresh YAML file itself. If you want to write scripts or programs that use the Codefresh variables, you need to make them aware of the environment variable form. +. + +## System Provided Variables + +All system provided variables will also be automatically injected to any freestyle step as environment variables. + +> It is important to understand that all Git related variables such `CF_BRANCH`, `CF_COMMIT_MESSAGE`, `CF_REVISION` etc. are coming directly from the Git provider you use and have the same limitations of that provider. For example GitLab is sending less information in pull request events than normal pushes, and Bitbucket sends only the short hash of a commit in pull request events. We suggest you read the documentation of your Git provider first to understand what information is available for every Git event + +{: .table .table-bordered .table-hover} +| Variable | Description | +| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {% raw %}`${{CF_REPO_OWNER}} `{% endraw %} | Repository owner. | +| {% raw %}`${{CF_REPO_NAME}}`{% endraw %} | Repository name. | +| {% raw %}`${{CF_BRANCH}}`{% endraw %} | Branch name (or Tag depending on the payload json) of the Git repository of the main pipeline, at the time of execution.
You can also use {% raw %}`${{CF_BRANCH_TAG_NORMALIZED}}`{% endraw %} to get the branch name normalized. It will be without any chars that are illegal in case the branch name were to be used as the Docker image tag name. You can also use {% raw %}`${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}`{% endraw %} to force lowercase. | +| {% raw %}`${{CF_BASE_BRANCH}}`{% endraw %} | The base branch used during creation of Tag | +| {% raw %}`${{CF_PULL_REQUEST_ACTION}}`{% endraw %} | The pull request action. Values are those defined by your Git provider such as [GitHub](https://developer.github.com/webhooks/), [GitLab](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html), [Bitbucket](https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html) etc. | +| {% raw %}`${{CF_PULL_REQUEST_TARGET}}`{% endraw %} | The pull request target branch | +| {% raw %}`${{CF_PULL_REQUEST_NUMBER}}`{% endraw %} | The pull request number | +| {% raw %}`${{CF_PULL_REQUEST_ID}}`{% endraw %} | The pull request id | +| {% raw %}`${{CF_PULL_REQUEST_LABELS}}`{% endraw %} | The labels of pull request (GitHub and GitLab only) | +| {% raw %}`${{CF_COMMIT_AUTHOR}}`{% endraw %} | Commit author. | +| {% raw %}`${{CF_BUILD_INITIATOR}}`{% endraw %} | The person (username) that started the build. If the build was started by a Git webhook (e.g. from a Pull request) it will hold the webhook user. Notice that if a build is restarted manually it will always hold the username of the person that restarted it. | +| {% raw %}`${{CF_ACCOUNT}}`{% endraw %} | Codefresh account for this build | +| {% raw %}`${{CF_COMMIT_URL}}`{% endraw %} | Commit url. | +| {% raw %}`${{CF_COMMIT_MESSAGE}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
The messages quotes are escaped (i.e. ' is not \', " is now \"). | +| {% raw %}`${{CF_COMMIT_MESSAGE_ESCAPED}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
Special characters are escaped. | +| {% raw %}`${{CF_REVISION}}`{% endraw %} | Revision of the Git repository of the main pipeline, at the time of execution.
You can also use {% raw %}`${{CF_SHORT_REVISION}}`{% endraw %} to get the abbreviated 7-character revision hash, as used in Git. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_SHORT_REVISION}}`{% endraw %} | +| {% raw %}`${{CF_VOLUME_NAME}}`{% endraw %} | Refers to the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) between [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). Normally you only need to define this in [compositions]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/). In freestyle steps, it is automatically present without any extra configuration. | +| {% raw %}`${{CF_VOLUME_PATH}}`{% endraw %} | Refers to the mounted path of the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) inside a Freestyle container. In the current implementation it expands to `/codefresh/volume`. | +| {% raw %}`${{CF_BUILD_TRIGGER}}`{% endraw %} | Will be an indication of the current build was triggered: *build: The build was triggered from the build button* webhook: The build was triggered from a control version webhook | +| {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | The build id. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | +| {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | The timestamp the build was created. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | +| {% raw %}`${{CF_BUILD_URL}}`{% endraw %} | The URL to the build in Codefresh | +| {% raw %}`${{CF_PIPELINE_NAME}}`{% endraw %} | The full path of the pipeline, i.e. "project/pipeline" | +| {% raw %}`${{CF_STEP_NAME}}`{% endraw %} | the name of the step, i.e. "MyUnitTests" | +| {% raw %}`${{CF_URL}}`{% endraw %} | The URL of Codefresh system | +| {% raw %}`${{CI}}`{% endraw %} | The value is always `true` | +| {% raw %}`${{CF_KUBECONFIG_PATH}}`{% endraw %} | Path to injected kubeconfig if at least one Kubernetes cluster [is configured]({{site.baseurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/). You can easily run [custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) since it is automatically setup by Codefresh in all pipelines. | +| Any variable specified in the pipeline settings | For example, if you configure the pipeline settings with a variable named PORT, you can put the variable in your YAML build descriptor as {% raw %}`${{PORT}}`{% endraw %}. | + +## Context Related Variables +Context related variables are created dynamically during the workflow execution and according to the used steps. + +{: .table .table-bordered .table-hover} +| Variable | Description | +| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Working Directories** | For example, you can set the working directory of step `A` with a variable named after a previously executed step, step `B`. Therefore, setting step `A` with {% raw %}`working-directory:${{B}}`{% endraw %} means that step `A` executes in the same working directory as step `B`. | +| **Images** | You can set the candidate field of the push step with a variable named after a previously executed build step. Since the details of a created image are not necessarily known ahead of time, the variable can create an association to an optionally dynamic image name. Therefore, setting push step `A` with {% raw %}`candidate:${{B}}`{% endraw %} means that step `A` will push the image built by step `B`. Note that this capability works only for `candidate` and `image` fields in Codefresh steps. | + +A very common pattern in Codefresh pipelines, is to create a Docker image in one step, and then run a command on its container in the next step (e.g. run [unit tests]({{site.baseurl}}/docs/testing/unit-tests/)): + +`YAML` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-own-app + MyUnitTests: + title: Running Unit tests + image: ${{MyAppDockerImage}} + commands: + - ./my-unit-tests.sh +{% endraw %} +{% endhighlight %} + +In the example above you can see the `MyAppDockerImage` variable that denotes a Docker image created dynamically within this single pipeline. In the second step we use it as a Docker context in order to run unit tests. See also the [unit testing example app]({{site.baseurl}}/docs/yaml-examples/examples/run-unit-tests/). + +## Step variables + +Every [step]({{site.baseurl}}/docs/codefresh-yaml/steps/) in a Codefresh pipeline also exposes several built-in variables. You can access them via the global `steps` parent variable. + + * Each step creates a variable based on the name of the step. You can then use the members of each variable for status conditions such as: `steps.MyUnitTests.result == 'error'` for a step called `MyUnitTests`. + * To access variables that have a non-standard (i.e. only alphanumeric and _ characters) names, use the Variable() function. + +### Step Member variables + +Variables that are created by steps can have members. The members depend on the step type. For example if you have a build step named `myBuildStep` you can get the ID of the docker image that gets created with {% raw %}`echo ${{steps.myBuildStep.imageId}}`{% endraw %} + +{: .table .table-bordered .table-hover} +| Step Type | Members | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| All step types | {::nomarkdown}
  • name
  • type
  • description
  • workingDirectory
  • result
{:/} | +| [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | - | +| [**Composition**]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) | - | +| [**Build**]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | {::nomarkdown}
  • imageName
  • imageTagName
  • imageId
{:/} | +| [**Git-clone**]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) | {::nomarkdown}
  • revision
  • repo
{:/} | +| [**Push**]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) | {::nomarkdown}
  • registry
  • imageId
  • imageRepoDigest
{:/} | +| [**Approval**]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) | {::nomarkdown}
  • authEntity.name
  • authEntity.type
{:/} | + + + +## GitHub Release Variables + +GitHub allows you to create [releases](https://help.github.com/articles/creating-releases/) for marking specific Git tags for general availability. + +You can set a [trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) for GitHub releases. When a GitHub release happens, the following variables are also available: + + + +{: .table .table-bordered .table-hover} +| Variable | Description | +| --------------- | ------------------------------------------------------ | +| {% raw %}`${{CF_RELEASE_NAME}}`{% endraw %} | GitHub release title | +| {% raw %}`${{CF_RELEASE_TAG}}`{% endraw %} | Git tag version | +| {% raw %}`${{CF_RELEASE_ID}}`{% endraw %} | Internal ID for this release | +| {% raw %}`${{CF_PRERELEASE_FLAG}}`{% endraw %} | true if the release if marked as non-production ready, false if it is ready for production | + +## GitHub Pull Request Variables + +When a pull request is closed in GitHub, the following variables are also available + +{: .table .table-bordered .table-hover} +| Variable | Description | +| --------------- | ------------------------------------------------------ | +| {% raw %}`${{CF_PULL_REQUEST_MERGED}}`{% endraw %} | true if the pull request was merged to base branch | +| {% raw %}`${{CF_PULL_REQUEST_HEAD_BRANCH}}`{% endraw %} | the head branch of the PR (the branch that we want to merge to master) | +| {% raw %}`${{CF_PULL_REQUEST_MERGED_COMMIT_SHA}}`{% endraw %} | the commit SHA on the base branch after the pull request was merged (in most cases it will be master) | +| {% raw %}`${{CF_PULL_REQUEST_HEAD_COMMIT_SHA}}`{% endraw %} | the commit SHA on the head branch (the branch that we want to push) | + +## User Provided Variables + +User provided variables can be defined at 6 levels: + +1. Manually within a step using the [export](http://linuxcommand.org/lc3_man_pages/exporth.html) command or in any **subsequent** step with the [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) command +1. [Freestyle Step Definition]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/#examples) (using the `environment` field) +1. Specific build Execution (after clicking the "Build" button open the "Build Variables" section, or use the [CLI]({{site.baseurl}}/docs/integrations/codefresh-api/#example---triggering-pipelines)) +1. Pipeline Definition (under "Environment variables" section in the [pipeline view]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#creating-new-pipelines)) +1. [Shared Configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) (defined under your account settings, and used using the "Import from shared configuration" button under the "Environment Variables" section in the pipeline view) +1. Variables defined on the Project level (Under the variables tab on any project view) + +The options are listed in order of priority (from the most important to the least important), so in case of multiple variables defined at different locations with the same name, the order of overriding will be as listed here. + +For example if a pipeline variable is defined both in project level and as an execution parameter of a specific build, then the final result will be the value defined as a build parameter and the project level variable will not take effect. + +## Exporting environment variables from a freestyle step + +Steps defined inside steps are scoped to the step they were created in (even if you used the `export` command). In order to allow using variables across steps, we provide a shared file that facilitates variables importing and exporting. There are two ways to add variables to this file: + +### Using cf_export command +Within every freestyle step, the `cf_export` command allows you to export variables across steps (by writing to the shared variables file). + +> The variables exported with cf_export overrides those at the pipeline-level. + +You can either: +- Explicitly state a VAR=VAL pair +- State the name of an existing *exported* environment variable (like EXISTING_VAR). + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + freestyle-step-1: + description: Freestyle step.. + title: Free styling + image: alpine:latest + commands: + # Normal export will only work in a single step + - export EXISTING_VAR=www.example.com + + # CF export will now work in all other subsequent steps + - cf_export VAR1=alpine:latest VAR2=VALUE2 EXISTING_VAR + + freestyle-step-2: + description: Freestyle step.. + title: Free styling 2 + image: ${{VAR1}} + commands: + - echo $VAR2 + - echo http://$EXISTING_VAR/index.php +{% endraw %} +{% endhighlight %} + +Notice that `cf_export` has the same syntax structure as the [bash export command](https://www.gnu.org/software/bash/manual/html_node/Environment.html). This means that when you use it you **don't** need any dollar signs for the variable created/assigned. + +``` +cf_export $MY_VAR # Don't do this +cf_export MY_VAR # Correct syntax +``` + +Also notice that `cf_export` works on *subsequent* steps only. If you want to export a variable right away in the present step and all the rest of the steps you need to do the following: + +``` +export MY_VAR='example' # Will make MY_VAR available in this step only +cf_export MY_VAR='example' # Will also make MY_VAR available to all steps after this one +``` + +There is nothing really magic about `cf_export`. It is a normal script. You can see its contents on your own by entering the command `cat /codefresh/volume/cf_export` on any [Codefresh freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) inside a pipeline. + +For more information on its limitations see the [troubleshooting page]({{site.baseurl}}/docs/troubleshooting/common-issues/cf-export-limitations/). + + + +### Directly writing to the file + +For more advanced use cases, you can write directly to the shared variable file that Codefresh reads to understand which variables need to be available to all steps. This file has a simple format where each line is a variable and its value in the form of `VARIABLE=VALUE`. The `cf_export` command mentioned in the previous section is just a shorthand for writing on this file. + +The variables file is available inside freestyle steps in the following path: **`{% raw %}${{CF_VOLUME_PATH}}{% endraw %}/env_vars_to_export`** + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + freestyle-step-1: + description: Freestyle step.. + title: Free styling + image: alpine:latest + commands: + - echo VAR1=192.168.0.1 >> ${{CF_VOLUME_PATH}}/env_vars_to_export + - echo hey=alpine:3.9 >> ${{CF_VOLUME_PATH}}/env_vars_to_export + + freestyle-step-2: + description: Freestyle step.. + title: Free styling 2 + image: ${{hey}} + commands: + - echo http://$VAR1/index.php +{% endraw %} +{% endhighlight %} + +Use this technique if you have complex expressions that have issues with the `cf_export` command. + +## Masking variables in logs + +Codefresh has the built-in capabililty to automatically mask variables in logs if they are encrypted. The values of encrypted variables will be replaced with asterisks in build logs. + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/variables/masked-variables.png" +url="/images/codefresh-yaml/variables/masked-variables.png" +alt="Masked variables" +caption="Masked variables" +max-width="80%" +%} + +The variables can be defined in any of the usual ways Codefresh offers such as [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) or [within the pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings): + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/variables/encrypted-variables.png" +url="/images/codefresh-yaml/variables/encrypted-variables.png" +alt="Encrypted variables" +caption="Encrypted variables" +max-width="60%" +%} + +>Notice that this feature is currently available only in Enterprise accounts. + + +## Escape Characters +When passing special characters through environmental variables `\` can be used as an escape character. For example if you were passing a cassandra connection string you might do something like `Points\=hostname\;Port\=16376\;Username\=user\;Password\=password` + +This will safely escape `;` and `=`. + +## What to read next + +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) +* [Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) diff --git a/_docs/pipelines/what-is-the-codefresh-yaml.md b/_docs/pipelines/what-is-the-codefresh-yaml.md new file mode 100644 index 00000000..36f3344f --- /dev/null +++ b/_docs/pipelines/what-is-the-codefresh-yaml.md @@ -0,0 +1,378 @@ +--- +title: "Codefresh YAML" +description: "How to define Codefresh pipelines in a declarative manner" +group: codefresh-yaml +redirect_from: + - /docs/codefresh-yaml/ + - /docs/what-is-the-codefresh-yaml + - /docs/what-is-the-codefresh-yaml/ + - /docs/codefresh-yaml/working-directories/ + - /docs/working-directories/ +toc: true +--- + +Codefresh offers its own built-in format for creating pipelines. The pipeline specification is +based on the YAML syntax allowing you to describe your pipelines in a completely declarative manner. + +Using Codefresh yaml is the recommended way to [create pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/). + +## Simple example for codefresh.yml + +Here is a very minimal example: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + build_image: + type: build + description: Building the image... + image-name: myuser/myservice + tag: develop # {% raw %}${{CF_BRANCH}}{% endraw %} + + perform_tests: + image: node:5 + working_directory: {% raw %}${{main_clone}}{% endraw %} + description: Performing unit tests... + commands: + - npm install gulp -g + - npm install + - gulp unit_test +{% endhighlight %} + +It contains two [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), one named *build_image* that creates a docker image, and another one called *perform_tests* that runs unit test with `gulp`. + +If you want to know more about how steps work in Codefresh make sure to read [the introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) first, before moving on. + +## Basic pipeline syntax + +You can customize your build environment (pipeline) by using the Codefresh YAML file, ```codefresh.yml```. Codefresh uses the build specifications in the ```codefresh.yml``` file to execute your build. The ```codefresh.yml``` can be basic or it can include intricate build specifications. + +A YAML file is comprised of a series of steps that are executed in the order in which they are specified. + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' + +steps: + step-name: + [step-contents] + another-step: + [step-contents] + the-very-last-step: + [step-contents] +{% endhighlight %} + +You must define a step type for each step, unless you are using a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). Each step uses Docker images and containers as facilitators for execution. For example, the [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) step spins up a container and executes the specified shell commands from the YAML file. + +The step names should be unique within the same pipeline. This mainly affects the visualization of the pipeline when it runs. + +Each step produces a resource, which you can [reference](https://github.com/codefresh-contrib/python-flask-sample-app/blob/master/codefresh.yml#L23) in other steps, and are executed in real-time. For example, a [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) step can reference an image that was produced by a [**Build**]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) step. This allows you to chain steps together and create highly-customized builds. + +
+##### Variables + +Steps chaining and referencing is possible due to implementation of variables in yml file - read more on relevant [section]({{site.baseurl}}/docs/codefresh-yaml/variables/) +
+ +{: .table .table-bordered .table-hover} +| Step Type | Description | +| ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| [Freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | Executes one or more shell commands in a container similar to `docker run`. | +| [Build]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | Builds a Docker image like `docker build`. | +| [Push]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) | Pushes a Docker image to an external registry similar to `docker tag` and `docker push`. | +| [Git Clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) | Overrides the default git clone behavior. | +| [Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) | Starts a Docker Composition like `docker-compose`. Discarded once pipelines finishes. | +| [Launch Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/launch-composition/) | Starts a long term Docker composition that stays up after the end of the pipeline. | +| [Deploy]({{site.baseurl}}/docs/codefresh-yaml/steps/deploy/) | Deploys to Kubernetes clusters. | +| [Approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) | Pauses a pipeline and waits for human intervention. | + + +For more information on creating your own step, see the [steps page]({{site.baseurl}}/docs/codefresh-yaml/steps/). + +You can also see the [full YAML specification]({{site.baseurl}}/docs/integrations/codefresh-api/#full-pipeline-specification) supported for pipelines. Note however that several fields are only accessible by using the [Codefresh API]({{site.baseurl}}/docs/integrations/codefresh-api) or [CLI](https://codefresh-io.github.io/cli/). + +## Yaml validation + +If you are editing Codefresh yaml within the Codefresh GUI, the editor will automatically highlight errors as they happen. + +This allows you to make quick edits (and possibly run some builds) straight from the GUI. Once you are happy with your pipeline you should commit it to your repository as `codefresh.yml` (pipeline as code). + +{% include +image.html +lightbox="true" +file="/images/codefresh-yaml/inline-editor.png" +url="/images/codefresh-yaml/inline-editor.png" +alt="Graphical Inline Yaml Editor" +caption="Graphical Inline Yaml Editor" +max-width="50%" +%} + +You can also validate the pipeline yaml outside of the UI by using the [Codefresh CLI](https://codefresh-io.github.io/cli/). The CLI has a [validate parameter](https://codefresh-io.github.io/cli/validation/) that can check one or more files for syntax errors + +{% highlight shell %} +{% raw %} +$ codefresh validate codefresh.yml +Yaml not valid: + - "invalid-property" is not allowed +{% endraw %} +{% endhighlight %} + +For more information on where the YAML file can be stored see the [creating pipelines page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/). + +## Execution flow + +By default, Codefresh will execute all steps in the yaml file and instantly fail the build, if any step +presents an error. To change this behavior add the `fail_fast:false` property in any step that you wish to be ignored +in case of errors. + +For example, if you have a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that runs integration tests, and you don't want the whole pipeline +to fail if any of the tests fail, add the `fail_fast` line to that step: + + +{% highlight yaml %} +perform_tests: + image: node:9 + description: Running integration tests + fail_fast: false + commands: + - gulp integration_test +{% endhighlight %} + +Now the pipeline will continue to run even if the step `perform_tests` fails. + +Notice also that by default Codefresh pipelines run in *sequential mode*. All steps will be executed one after +the other and in the same order as included in the `codefresh.yml` file. + +If you wish to use parallel steps in your pipelines, see the [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) page. + +## Working directories + +In the context of a step, a working directory can be of the following type: + +{: .table .table-bordered .table-hover} +| Working Directory | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Empty | Defaults to the [Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) (found at `/codefresh/volume`). If there is a [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) with the special name `main_clone` then the default working directory for built-in steps is now the [project folder]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) that was checked out - this only applies to [built-in]({{site.baseurl}}/docs/codefresh-yaml/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/codefresh-yaml/steps/#creating-a-typed-codefresh-plugin). | +| Variable that contains the ID of a [Git-Clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step | Runs the step within the cloned directory. | +| Variable that contains the ID of any other step | Runs the step within the same working directory that the specified was executed. This option is not available for for [**Git-Clone**]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) steps. | +| Absolute filesystem path | Treated as is within the container. | +| Relative filesystem path | Treated as relative path from the cloned directory of the service | +| 'IMAGE_WORK_DIR' | Use this value in order to use the image working directory for example:
`working_directory: IMAGE_WORK_DIR` | + +## Retrying a step + +Sometimes you want to retry a step that has a problem. Network hiccups, transient failures and flaky test environments are common problems that prevent pipelines from working in a predictable manner. + +Codefresh allows you to retry any of your steps with the built-in syntax: + + `yaml` +{% highlight yaml %} +{% raw %} +step-name: + [step-contents] + retry: + maxAttempts: 5 + delay: 5 + exponentialFactor: 2 +{% endraw %} +{% endhighlight %} + +The `retry:` block has the following parameters: + + * `maxAttempts` defines how many times this step will run again if there are execution errors (default is 1 and the Max. is 10). + * `delay` is the number of seconds to wait before each attempt (default is 5 seconds and the Max. is 60 seconds). + * `exponentialFactor` defines how many times the delay should be multiplied by itself after each attempt (default is 1 and Max. is 5). + +All parameters are optional. The exponentialFactor works like this: +* exponentialFactor=1, delay=5 => each time wait 5 seconds before trying again, no matter the number of attempts. +* exponentialFactor=2, delay=5 => first retry will have a delay of 25 seconds, third will have 125 and so on. + + +Here is a full example: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-own-app + retry: + maxAttempts: 2 + MyUnitTests: + title: Running Unit tests + image: ${{MyAppDockerImage}} + commands: + - ./my_unit_tests.sh + retry: + maxAttempts: 3 + delay: 5 + PushingToRegistry: + type: push + title: Pushing To Registry + candidate: ${{MyAppDockerImage}} + tag: '${{CF_BRANCH}}' + retry: + maxAttempts: 3 + delay: 3 + exponentialFactor: 2 +{% endraw %} +{% endhighlight %} + +Notice that Codefresh also provides the following variables that allow you change your script/applications according to the retry attempts: + +* `CF_CURRENT_ATTEMPT` contains the number of current retry attempt. +* `CF_MAX_ATTEMPTS` contains all the number of total attempts defined. + +The retry mechanism is available for all kinds of [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/). + +## Escaping strings + +If you want to use strings inside your pipeline that create conflicts with the Codefresh syntax parser (for example they are YAML themselves) you need +to escape them using multi-line strings with the `>-` and `|-` characters. + +The following pipeline is not parsed correctly because the echo command is using the yaml `:` character + +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + test: + title: "Running test" + type: "freestyle" + image: "alpine:3.9" + commands: + - echo hello: world +{% endraw %} +{% endhighlight %} + +You can fix this issue by using a multi-line YAML string: + +{% highlight yaml %} +{% raw %} +version: "1.0" +steps: + test: + title: "Running test" + type: "freestyle" + image: "alpine:3.9" + commands: + - |- + echo hello: world +{% endraw %} +{% endhighlight %} + +The `|-` character keeps the line breaks of the text (but removes the last one). Use the `>-` character if you want to convert line breaks to spaces. +For more information see the [YAML specification](https://yaml.org/spec/1.2/spec.html). + +## Using YAML anchors to avoid repetition + +Codefresh also supports yaml anchors, references and extends. These allow you to keep +your pipeline [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +For example, let's say that you have two freestyle steps: + +1. The first one fills a MySQL server with data. +1. The second one runs integration tests that use the MySQL server. + +Here is the respective pipeline: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + preLoadDatabase: + title: Loading Data + image: alpine + commands: + - printenv + - echo "Loading DB" + environment: &my_common_envs + - MYSQL_HOST=mysql + - MYSQL_USER=user + - MYSQL_PASS=password + - MYSQL_PORT=3351 + runTests: + title: Integration tests + image: alpine + commands: + - printenv + - echo "Running tests" + environment: *my_common_envs # Same MYSQL_HOST, MYSQL_USER etc. +{% endhighlight %} + +Instead of repeating the same environment variables in both steps, we can create them once and then just reference them in the second step with the `*` character. + +You also define anchors at the top of the pipeline in the special `indicators` block: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' + +indicators: + - environment: &my_common_envs + - MYSQL_HOST=mysql + - MYSQL_USER=user + - MYSQL_PASS=password + - MYSQL_PORT=3351 + +steps: + preLoadDatabase: + title: Loading Data + image: alpine + commands: + - printenv + - echo "Loading DB" + environment: *my_common_envs # Same MYSQL_HOST, MYSQL_USER etc. + runTests: + title: Integration tests + image: alpine + commands: + - printenv + - echo "Running tests" + environment: *my_common_envs # Same MYSQL_HOST, MYSQL_USER etc. + +{% endhighlight %} + + +Finally. you also extend steps like below: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + deploy_to_k8_staging: &my_basic_deployment + title: deploying to cluster + type: deploy + kind: kubernetes + cluster: myStagingCluster + namespace: sales + service: my-python-app + deploy_to_k8_prod: + <<: *my_basic_deployment + cluster: myProdCluster # only cluster differs, everything else is the same + +{% endhighlight %} + +Here we deploy to two kubernetes clusters. The first step defines the staging deployment. +For the second step, we extend the first one and only change the name of the cluster +to point to production. Everything else (i.e. namespace and service) are exactly the same. + + +## What to read next + +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) +* [Advanced workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [YAML examples]({{site.baseurl}}/docs/yaml-examples/examples/) + + + + + + + diff --git a/_docs/pipelines/concurrency-limit.md b/_docs/workflows/concurrency-limit.md similarity index 100% rename from _docs/pipelines/concurrency-limit.md rename to _docs/workflows/concurrency-limit.md diff --git a/_docs/pipelines/configure-artifact-repository.md b/_docs/workflows/configure-artifact-repository.md similarity index 100% rename from _docs/pipelines/configure-artifact-repository.md rename to _docs/workflows/configure-artifact-repository.md diff --git a/_docs/pipelines/create-pipeline.md b/_docs/workflows/create-pipeline.md similarity index 100% rename from _docs/pipelines/create-pipeline.md rename to _docs/workflows/create-pipeline.md diff --git a/_docs/pipelines/docker-operations.md b/_docs/workflows/docker-operations.md similarity index 100% rename from _docs/pipelines/docker-operations.md rename to _docs/workflows/docker-operations.md diff --git a/_docs/pipelines/marketplace.md b/_docs/workflows/marketplace.md similarity index 100% rename from _docs/pipelines/marketplace.md rename to _docs/workflows/marketplace.md diff --git a/_docs/pipelines/nested-workflows.md b/_docs/workflows/nested-workflows.md similarity index 100% rename from _docs/pipelines/nested-workflows.md rename to _docs/workflows/nested-workflows.md diff --git a/_docs/pipelines/sharing-file-system.md b/_docs/workflows/sharing-file-system.md similarity index 100% rename from _docs/pipelines/sharing-file-system.md rename to _docs/workflows/sharing-file-system.md diff --git a/_docs/pipelines/using-secrets.md b/_docs/workflows/using-secrets.md similarity index 100% rename from _docs/pipelines/using-secrets.md rename to _docs/workflows/using-secrets.md diff --git a/_docs/pipelines/workflows.md b/_docs/workflows/workflows.md similarity index 100% rename from _docs/pipelines/workflows.md rename to _docs/workflows/workflows.md From 6f8b14b6b9b60aec45a35ff978d0f3e6962764d1 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Thu, 1 Dec 2022 15:43:10 +0200 Subject: [PATCH 2/8] Update pipeline topics Xrefs to new bucket --- _docs/pipelines/advanced-workflows.md | 1 - _docs/pipelines/build-status.md | 2 +- .../pipelines/condition-expression-syntax.md | 42 +++--- .../conditional-execution-of-steps.md | 118 +++++++++++++++-- _docs/pipelines/docker-image-metadata.md | 2 +- .../introduction-to-codefresh-pipelines.md | 48 ++++--- _docs/pipelines/pipelines.md | 73 ++++++----- _docs/pipelines/steps.md | 121 +++++++++--------- _docs/pipelines/steps/approval.md | 22 ++-- _docs/pipelines/steps/build.md | 23 ++-- _docs/pipelines/steps/composition.md | 20 +-- _docs/pipelines/steps/deploy.md | 13 +- _docs/pipelines/steps/freestyle.md | 29 ++--- _docs/pipelines/steps/git-clone.md | 38 +++--- _docs/pipelines/steps/launch-composition.md | 23 ++-- _docs/pipelines/steps/push.md | 54 ++++---- _docs/pipelines/triggers.md | 58 ++++----- _docs/pipelines/triggers/azure-triggers.md | 27 ++-- _docs/pipelines/triggers/cron-triggers.md | 16 +-- .../pipelines/triggers/dockerhub-triggers.md | 31 +++-- _docs/pipelines/triggers/git-triggers.md | 62 +++++---- _docs/pipelines/triggers/helm-triggers.md | 21 ++- _docs/pipelines/triggers/jfrog-triggers.md | 19 +-- _docs/pipelines/triggers/quay-triggers.md | 15 ++- 24 files changed, 485 insertions(+), 393 deletions(-) diff --git a/_docs/pipelines/advanced-workflows.md b/_docs/pipelines/advanced-workflows.md index 06eedc38..209a339d 100644 --- a/_docs/pipelines/advanced-workflows.md +++ b/_docs/pipelines/advanced-workflows.md @@ -960,7 +960,6 @@ The possible values for `workflow.result` are: * [Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) * [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) * [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) diff --git a/_docs/pipelines/build-status.md b/_docs/pipelines/build-status.md index 05a0ef40..98d48f27 100644 --- a/_docs/pipelines/build-status.md +++ b/_docs/pipelines/build-status.md @@ -1,7 +1,7 @@ --- title: "Public logs and status badges" description: "Embedding Status Images and viewing public logs" -group: configure-ci-cd-pipeline +group: pipelines toc: true redirect_from: - /docs/build-status diff --git a/_docs/pipelines/condition-expression-syntax.md b/_docs/pipelines/condition-expression-syntax.md index 4fd3e774..8e1ea6c6 100644 --- a/_docs/pipelines/condition-expression-syntax.md +++ b/_docs/pipelines/condition-expression-syntax.md @@ -29,17 +29,17 @@ A condition expression is a basic expression that is evaluated to true/false (to ### Types {: .table .table-bordered .table-hover} -| Type | True/False Examples | True/False | -| ------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Type | True/False Examples | True/False | +| ------- | ----------------------------------------- | --------------| | String | True: "hello"
False: "" | {::nomarkdown}
  • String with content = true
  • Empty string = false
  • String with content = true
String comparison is lexicographic.{:/} | -| Number | True: 5
True: 3.4
True: 1.79E+308 | {::nomarkdown}
  • Any number other than 0 = true.
  • 0 = false
{:/} | -| Boolean | True: true
False: false | {::nomarkdown}
  • True = true
  • False = false
{:/} | -| Null | False: null | Always false | +| Number | True: 5
True: 3.4
True: 1.79E+308 | {::nomarkdown}
  • Any number other than 0 = true.
  • 0 = false
{:/} | +| Boolean | True: true
False: false | {::nomarkdown}
  • True = true
  • False = false
{:/} | +| Null | False: null | Always false | ### Variables -You can use the User Provided variables as explained in the [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) documentation including the [variables -exposed by each individual pipeline step]({{site.baseurl}}/docs/codefresh-yaml/variables/#step-variables). +You can use the User Provided variables as explained in [Variables]({{site.baseurl}}/docs/pipelines/variables/), including the [variables +exposed by each individual pipeline step]({{site.baseurl}}/docs/pipelines/variables/#step-variables). ### Unary Operators @@ -79,20 +79,20 @@ exposed by each individual pipeline step]({{site.baseurl}}/docs/codefresh-yaml/v {: .table .table-bordered .table-hover} | Function Name | Parameters | Return value | Example | | ------------- | ------------------ | -------------- | ----------------------- | -| String | 0: number or string | String of input value. | `String(40) == '40'` | -| Number | 0: number or string | Number of input value. | `Number('50') == 50`
`Number('hello')` is invalid | -| Boolean | 0: number or string | Boolean of input value. | `Boolean('123') == true`
`Boolean('') == false`
`Boolean(583) == true`
`Boolean(0) == false` | -| round | 0: number | Rounded number. | `round(1.3) == 1`
`round(1.95) == 2` | -| floor | 0: number | Number rounded to floor. | `floor(1.3) == 1`
`floor(1.95) == 1` | -| upper | 0: string | String in upper case. | `upper('hello') == 'HELLO'` | -| lower | 0: string | String in lower case. | `lower('BYE BYE') == 'bye bye'` | -| trim | 0: string | Trimmed string. | `trim(" abc ") == "abc"` | -| trimLeft | 0: string | Left-trimmed string. | `trimLeft(" abc ") == "abc "` | -| trimRight | 0: string | Right-trimmed string. | `trimRight(" abc ") == " abc"` | -| replace | 0: string - main string
1: string - substring to find
2: string - substring to replace | Replace all instances of the sub-string (1) in the main string (0) with the sub-string (2). | `replace('hello there', 'e', 'a') == 'hallo thara'` | -| substring | 0: string - main string
1: string - index to start
2: string - index to end | Returns a sub-string of a string. | `substring("hello world", 6, 11) == "world"` | -| length | string | Length of a string. | `length("gump") == 4` | -| includes | 0: string - main string
1: string - string to search for | Whether a search string is located within the main string. | `includes("codefresh", "odef") == true` | +| String | 0: number or string | String of input value. | `String(40) == '40'` | +| Number | 0: number or string | Number of input value. | `Number('50') == 50`
`Number('hello')` is invalid | +| Boolean | 0: number or string | Boolean of input value. | `Boolean('123') == true`
`Boolean('') == false`
`Boolean(583) == true`
`Boolean(0) == false` | +| round | 0: number | Rounded number. | `round(1.3) == 1`
`round(1.95) == 2` | +| floor | 0: number | Number rounded to floor. | `floor(1.3) == 1`
`floor(1.95) == 1` | +| upper | 0: string | String in upper case. | `upper('hello') == 'HELLO'` | +| lower | 0: string | String in lower case. | `lower('BYE BYE') == 'bye bye'` | +| trim | 0: string | Trimmed string. | `trim(" abc ") == "abc"` | +| trimLeft | 0: string | Left-trimmed string. | `trimLeft(" abc ") == "abc "`| +| trimRight | 0: string | Right-trimmed string. | `trimRight(" abc ") == " abc"` | +| replace | 0: string - main string
1: string - substring to find
2: string - substring to replace | Replace all instances of the sub-string (1) in the main string (0) with the sub-string (2). | `replace('hello there', 'e', 'a') == 'hallo thara'`| +| substring | 0: string - main string
1: string - index to start
2: string - index to end | Returns a sub-string of a string. | `substring("hello world", 6, 11) == "world"` | +| length | string | Length of a string. | `length("gump") == 4` | +| includes | 0: string - main string
1: string - string to search for | Whether a search string is located within the main string. | `includes("codefresh", "odef") == true` | | indexOf | 0: string - main string
1: string - string to search for | Index of a search string if it is found inside the main string | `indexOf("codefresh", "odef") == 1` | | match | 0: string - main string
1: string - regular expression string, [JS style](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) (Note: in JS strings, the backslash `\` is an escape character so in order to use a literal backslash, you need to escape it. For example: `"^\\d+$"` instead of `"^\d+$"`)
2: boolean - ignore case | Search for a regular expression inside a string, ignoring or not ignoring case | `match("hello there you", "..ll.", false) == true`
`match("hello there you", "..LL.", false) == false`
`match("hello there you", "hell$", true) == false`
`match("hello there you", "^hell", true) == true`
`match("hello there you", "bye", false) == false` | | Variable | string | Search for the value of a variable | `Variable('some-clone')` | diff --git a/_docs/pipelines/conditional-execution-of-steps.md b/_docs/pipelines/conditional-execution-of-steps.md index 56eea7d7..1019eaad 100644 --- a/_docs/pipelines/conditional-execution-of-steps.md +++ b/_docs/pipelines/conditional-execution-of-steps.md @@ -1,14 +1,16 @@ --- -title: "Conditional Execution of Steps" +title: "Conditional execution of steps" description: "Skip specific pipeline steps according to one or more conditions" -group: codefresh-yaml +group: pipelines redirect_from: - /docs/conditional-execution-of-steps/ toc: true --- For each step in a `codefresh.yml` file, you can define a set of conditions which need to be satisfied in order to execute the step. (An introduction to the `codefresh.yml` file can be found [here]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/).) -There are currently two main methods to define conditions: branch conditions and expression conditions. +There are currently two main methods to define conditions: +* Branch conditions +* Expression conditions ## Branch Conditions @@ -70,9 +72,9 @@ build-step: Alternatively, you can use more advanced condition expressions. -This follows the standard [condition expression syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/). In this case, you can choose to execute if ```all``` expression conditions evaluate to ```true```, or to execute if ```any``` expression conditions evaluate to ```true```. +This follows the standard [condition expression syntax](#condition-expression-syntax). In this case, you can choose to execute if ```all``` expression conditions evaluate to ```true```, or to execute if ```any``` expression conditions evaluate to ```true```. -> Note: Use "" around variables with text to avoid errors in processing the conditions. ex: "${{CF_COMMIT_MESSAGE}}" +> Note: Use "" around variables with text to avoid errors in processing the conditions. Example: "${{CF_COMMIT_MESSAGE}}" Here are some examples. Execute if the string ```[skip ci]``` is not part of the main repository commit message AND if the branch is ```master``` @@ -106,11 +108,103 @@ build-step: notFeatureBranch: 'match({% raw %}"${{CF_BRANCH}}"{% endraw %}, "^FB-", true) == false' {% endhighlight %} +Each step in `codefresh.yml` file can contain conditions expressions that must be satisfied for the step to execute. + +This is a small example of where a condition expression can be used: + `YAML` +{% highlight yaml %} +step-name: + description: Step description + image: image/id + commands: + - bash-command1 + - bash-command2 + when: + condition: + all: + executeForMasterBranch: "{% raw %}'${{CF_BRANCH}}{% endraw %}' == 'master'" +{% endhighlight %} + +### Condition expression syntax +A condition expression is a basic expression that is evaluated to true/false (to decide whether to execute or not to execute), and can have the following syntax: + +#### Types + +{: .table .table-bordered .table-hover} +| Type | True/False Examples | True/False | +| ------- | ----------------------------------------- | --------------| +| String | True: "hello"
False: "" | {::nomarkdown}
  • String with content = true
  • Empty string = false
  • String with content = true
String comparison is lexicographic.{:/} | +| Number | True: 5
True: 3.4
True: 1.79E+308 | {::nomarkdown}
  • Any number other than 0 = true.
  • 0 = false
{:/} | +| Boolean | True: true
False: false | {::nomarkdown}
  • True = true
  • False = false
{:/} | +| Null | False: null | Always false | + +#### Variables + +You can use the User Provided variables as explained in [Variables]({{site.baseurl}}/docs/pipelines/variables/), including the [variables +exposed by each individual pipeline step]({{site.baseurl}}/docs/pipelines/variables/#step-variables). + +#### Unary Operators + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| ---------- | --------------------- | +| `-` | Negation of numbers | +| `!` | Logical NOT | + +#### Binary Operators + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| --------------------------- | ----------- | +| Add, String Concatenation | `+` | +| Subtract | `-` | +| Multiply | `*` | +| Divide | `/` | +| Modulus | `%` | +| Logical AND | `&&` | +| Logical OR | `||` | + +#### Comparisons + +{: .table .table-bordered .table-hover} +| Operator | Operation | +| ----------- | ---------------------- | +| `==` | Equal to | +| `!=` | Not equal to | +| `>` | Greater than | +| `>=` | Greater than or equal | +| `<` | Less than | +| `<=` | Less than or equal | + +#### Functions + +{: .table .table-bordered .table-hover} +| Function Name | Parameters | Return value | Example | +| ------------- | ------------------ | -------------- | ----------------------- | +| String | 0: number or string | String of input value. | `String(40) == '40'` | +| Number | 0: number or string | Number of input value. | `Number('50') == 50`
`Number('hello')` is invalid | +| Boolean | 0: number or string | Boolean of input value. | `Boolean('123') == true`
`Boolean('') == false`
`Boolean(583) == true`
`Boolean(0) == false` | +| round | 0: number | Rounded number. | `round(1.3) == 1`
`round(1.95) == 2` | +| floor | 0: number | Number rounded to floor. | `floor(1.3) == 1`
`floor(1.95) == 1` | +| upper | 0: string | String in upper case. | `upper('hello') == 'HELLO'` | +| lower | 0: string | String in lower case. | `lower('BYE BYE') == 'bye bye'` | +| trim | 0: string | Trimmed string. | `trim(" abc ") == "abc"` | +| trimLeft | 0: string | Left-trimmed string. | `trimLeft(" abc ") == "abc "`| +| trimRight | 0: string | Right-trimmed string. | `trimRight(" abc ") == " abc"` | +| replace | 0: string - main string
1: string - substring to find
2: string - substring to replace | Replace all instances of the sub-string (1) in the main string (0) with the sub-string (2). | `replace('hello there', 'e', 'a') == 'hallo thara'`| +| substring | 0: string - main string
1: string - index to start
2: string - index to end | Returns a sub-string of a string. | `substring("hello world", 6, 11) == "world"` | +| length | string | Length of a string. | `length("gump") == 4` | +| includes | 0: string - main string
1: string - string to search for | Whether a search string is located within the main string. | `includes("codefresh", "odef") == true` | +| indexOf | 0: string - main string
1: string - string to search for | Index of a search string if it is found inside the main string | `indexOf("codefresh", "odef") == 1` | +| match | 0: string - main string
1: string - regular expression string, [JS style](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) (Note: in JS strings, the backslash `\` is an escape character so in order to use a literal backslash, you need to escape it. For example: `"^\\d+$"` instead of `"^\d+$"`)
2: boolean - ignore case | Search for a regular expression inside a string, ignoring or not ignoring case | `match("hello there you", "..ll.", false) == true`
`match("hello there you", "..LL.", false) == false`
`match("hello there you", "hell$", true) == false`
`match("hello there you", "^hell", true) == true`
`match("hello there you", "bye", false) == false` | +| Variable | string | Search for the value of a variable | `Variable('some-clone')` | +| Member | 0: string - variable name
1: string - member name | Search for the value of a variable member | `Member('some-clone', 'working-directory')` | + ## Execute steps according to the presence of a variable If a variable does not exist in a Codefresh pipeline, then it will simply stay as a string inside the definition. When the `{% raw %}${{MY_VAR}}{% endraw %}` variable is not available, the engine will literally print `{% raw %}${{MY_VAR}}{% endraw %}`, because that variable doesn't exist. -You can use this mechanism to decide which steps will be executed if a [variable]({{site.baseurl}}/docs/codefresh-yaml/variables/) exists or not. +You can use this mechanism to decide which steps will be executed if a [variable]({{site.baseurl}}/docs/pipelines/variables/) exists or not. @@ -146,10 +240,8 @@ Try running the pipeline above and see how it behaves when a variable called `MY >Notice that if you use this pattern a lot it means that you are trying to create a complex pipeline that is very smart. We suggest you create instead multiple [simple pipelines for the same project]({{site.baseurl}}/docs/ci-cd-guides/pull-request-branches/#trunk-based-development). -## What to read next - -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Condition syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) -* [Pull Requests and Branches]({{site.baseurl}}/docs/ci-cd-guides/pull-request-branches/) -* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/ +[Variables]({{site.baseurl}}/docs/pipelines/variables/) +[Pull Requests and Branches]({{site.baseurl}}/docs/ci-cd-guides/pull-request-branches/) +[Pipeline/Step hooks]({{site.baseurl}}/docs/pipelines/hooks/) diff --git a/_docs/pipelines/docker-image-metadata.md b/_docs/pipelines/docker-image-metadata.md index 061e0f0f..ca4f9ca6 100644 --- a/_docs/pipelines/docker-image-metadata.md +++ b/_docs/pipelines/docker-image-metadata.md @@ -36,7 +36,7 @@ Metadata values may be of the following types: | Percentage bar | use 0-100 value ending with % | 85% | | Link | use url | {% raw %}`${{CF_COMMIT_URL}}`{% endraw %} | -You can also use [Expression evaluations]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) to set metadata. +You can also use [Expression evaluations]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/#condition-expression-syntax) to set metadata. ## Annotate your images using Codefresh YAML You can annotate an image as part of it's builds process and also on post build steps. diff --git a/_docs/pipelines/introduction-to-codefresh-pipelines.md b/_docs/pipelines/introduction-to-codefresh-pipelines.md index fd87b5f1..ce33a186 100644 --- a/_docs/pipelines/introduction-to-codefresh-pipelines.md +++ b/_docs/pipelines/introduction-to-codefresh-pipelines.md @@ -1,7 +1,7 @@ --- title: "Introduction to Codefresh pipelines" description: "Understand how Codefresh pipelines work" -group: configure-ci-cd-pipeline +group: pipelines redirect_from: - /docs/introduction-to-codefresh-pipelines/ - /docs/configure-ci-cd-pipeline/ @@ -9,8 +9,9 @@ toc: true --- -The central component of the Codefresh Platform are pipelines. Pipelines are workflows that contain individual steps. -Each step is responsible for a specific action in the process. Pipelines can be used to: +The central component of the Codefresh platform for continuous integration (CI) are pipelines. Pipelines are workflows that contain individual steps, with each step responsible for a specific action in the CI process. + +Pipelines can be used to: * Compile and package code * Build Docker images @@ -29,7 +30,7 @@ caption="Codefresh pipelines" max-width="90%" %} -## Why Codefresh is different +## Why are Codefresh pipelines different? Codefresh offers unique characteristics in pipelines that serve as the cornerstone of the build/deploy process: @@ -62,8 +63,8 @@ image.html lightbox="true" file="/images/pipeline/introduction/steps-example1.png" url="/images/pipeline/introduction/steps-example1.png" -alt="Codefresh steps example 1" -caption="Pipeline with 3 steps" +alt="Pipeline with three steps" +caption="Pipeline with three steps" max-width="70%" %} @@ -72,7 +73,7 @@ max-width="70%" 1. The second step uses an image with s3 command line tools and uploads the test results to a bucket that holds test reports. 1. The helm step creates a Helm chart and pushes it to a Helm repository. -You don't need to contact Codefresh and ask them to add the s3 executable on the build runners. You just use a premade Docker image that contains it. The version used for Node is defined by you and if you wish to upgrade to another version +You don't need to contact Codefresh and ask them to add the S3 executable on the build runners. You just use a prebuilt Docker image that contains it. The version used for Node is defined by you and if you wish to upgrade to another version you simply change the definition of the pipeline. @@ -98,7 +99,7 @@ or your own) to use a build context in your step. This makes Codefresh a future- that exist now and all of them that will appear in the future. As long as there is a Docker image for a tool, Codefresh can use it in a pipeline without any extra configuration. -Codefresh also offers a [plugin marketplace](https://codefresh.io/steps/) with several existing plugins. +Codefresh also offers a [marketplace](https://codefresh.io/steps/) with several existing plugins. {% include image.html @@ -111,7 +112,7 @@ max-width="80%" %} -All plugins in the marketplace are open-source and we accept external contributions so you can easily add your own. +All plugins in the marketplace are open-source, and we accept external contributions so you can easily add your own. ### Sharing the workspace between build steps @@ -184,15 +185,14 @@ extra environment variables. ## Working with Codefresh pipelines -Now that we know the basics, we can see how you can take advantage of Docker-based pipelines in order -to build and deploy your projects. +Now that we know the basics, we can see how you can take advantage of Docker-based pipelines in order to build and deploy your projects. ### Cloning the source code -You can clone source code using the built-in [git-clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) as the first step in a Pipeline or run manually your own git clone commands in a freestyle step. Codefresh has built-in [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) with all popular git providers (both cloud and on-premises installations). +You can clone source code using the built-in [git-clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) as the first step in a Pipeline, or run manually your own git clone commands in a freestyle step. Codefresh has built-in [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) with all popular git providers (both cloud and on-premises installations). -Codefresh uses the shared volume as the parent folder of the project. So if your pipeline is connected to a GIT repo that contains `my-project` the following will happen: +Codefresh uses the shared volume as the parent folder of the project. So if your pipeline is connected to a Git repo that contains `my-project` the following will happen: * `/codefresh/volume` is the shared directory for all steps * `/codefresh/volume/my-project` is where the source code exists. This is also the current working directory @@ -208,15 +208,14 @@ caption="Codefresh checkout folder" max-width="80%" %} -There are three important points to consider regarding these folders. +There are three important points to consider regarding these folders: -First, the [working directory]({{ site.baseurl }}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#working-directories) of each step is by default the project folder (e.g. `/codefresh/volume/my-project`). Therefore +1. The [working directory]({{ site.baseurl }}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#working-directories) of each step is by default the project folder (e.g. `/codefresh/volume/my-project`). Therefore your build step can run commands exactly as you would run them locally (e.g. `npm install, pip install, mvn package, bundle install`). -Secondly, notice that the project folder is placed on the Codefresh volume, so by default it is also available to all other steps. The code that you checkout in the beginning, as well as all other files that are created on it, will -be available to all steps. Once you create `node_modules`, or any other folder that exists inside the project folder, it will automatically persist for all other steps. +1. Notice that the project folder is placed on the Codefresh volume, so by default it is also available to all other steps. The code that you check out in the beginning, as well as all other files that are created on it, are available to all steps. Once you create `node_modules`, or any other folder that exists inside the project folder, it will automatically persist for all other steps. -Finally, `/codefresh/volume` is an internal folder name and you should use `{% raw %}${{CF_VOLUME_PATH}}{% endraw %}` in your codefresh.yml file +1. Finally, `/codefresh/volume` is an internal folder name, and you should use `{% raw %}${{CF_VOLUME_PATH}}{% endraw %}` in your codefresh.yml file if you really want to reference this folder. You can also reference your project folder as `{% raw %}${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}{% endraw %}` if you need it. See the [System Provided Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/#system-provided-variables) section for more information. @@ -225,7 +224,7 @@ See the [System Provided Variables]({{site.baseurl}}/docs/codefresh-yaml/variabl We have already seen that Codefresh pipelines are based on Docker images and that each step runs inside the context of a Docker container. You might be wondering how you can run Docker commands directly inside a Codefresh pipeline. -The answer is that you don't. Even though in the future Codefresh might allow for Docker-in-Docker capabilities, at the moment this is not supported for security reason (only enterprise customers have access to the underlying Docker daemon). Any scripts that you already have that run Docker commands on their own will need to be adapted to Codefresh pipelines. +The answer is that you don't. Even though in the future Codefresh might allow for Docker-in-Docker capabilities, at the moment this is not supported for security reasons (only enterprise customers have access to the underlying Docker daemon). Any scripts that you already have that run Docker commands on their own will need to be adapted to Codefresh pipelines. Usually you want to run a docker command for four reasons: @@ -330,12 +329,11 @@ max-width="80%" Notice that each Pipeline in Codefresh is completely isolated from the other. They use a different Docker volume so the build context of each one cannot access files from the other. This may change in the future, but for the time being you should know that only steps within the same pipeline can share artifacts. -## What to read next - -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Build and Docker caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) +## Related articles +[Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +[Build and Docker caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) diff --git a/_docs/pipelines/pipelines.md b/_docs/pipelines/pipelines.md index 0a351dd5..e2109c9d 100644 --- a/_docs/pipelines/pipelines.md +++ b/_docs/pipelines/pipelines.md @@ -1,7 +1,7 @@ --- -title: "Creating Pipelines" -description: "How to define Pipelines in Codefresh" -group: configure-ci-cd-pipeline +title: "Creating pipelines" +description: "How to define pipelines in Codefresh" +group: pipelines redirect_from: - /docs/pipeline - /docs/pipeline/ @@ -14,11 +14,11 @@ redirect_from: toc: true --- -Before reading this page make sure that you are familiar with the theory behind Codefresh pipelines at the [introduction page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). +Before creating a pipeline, make sure you are familiar with the theory behind [Codefresh pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/). -## Pipeline Concepts +## Pipeline concepts -The aim of Codefresh pipelines is to have re-usable sequences of steps that can be used for different applications (or micro-services) via the use of git triggers. +The aim of Codefresh pipelines is to have re-usable sequences of steps that can be used for different applications (or micro-services) via the use of Git triggers. All the main concepts are shown below: @@ -32,13 +32,13 @@ caption="Pipeline concepts" max-width="60%" %} -* **Projects**: the top-level concept in Codefresh. You can create projects to group pipelines that are related. In most cases a single project will be a single application (that itself contains many micro-services). You are free to use projects as you see fit. For example, you could create a project for a specific Kubernetes cluster or a specific team/department. +* **Projects**: The top-level concept in Codefresh. Projects are used to group related pipelines. In most cases a single project will be a single application (that itself contains many micro-services). You are free to use projects as you see fit. For example, you could create a project for a specific Kubernetes cluster or a specific team/department. -* **Pipelines**: each project can have multiple pipelines. Pipelines that belong to a single project are easily managed all together. It is also very easy to create a new pipeline in a project by copying an existing pipeline. Notice that unlike other CI solutions a pipeline in Codefresh is **NOT** tied to a specific git repository. You should try to make your pipelines generic enough so that they can be reused for similar applications even when they exist in different git repositories (a fairly typical setup for microservices). +* **Pipelines**: Each project can have multiple pipelines. Pipelines that belong to a single project can be managed as a unit. You can also create a new pipeline by copying an existing pipeline. Notice that unlike other CI solutions, a pipeline in Codefresh is **NOT** tied to a specific Git repository. You should try to make your pipelines generic enough so that they can be reused for similar applications even when they exist in different Git repositories (a fairly typical setup for microservices). -* **Pipeline Steps**: each pipeline has a definition that defines the [pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) that are executed each time this pipeline is triggered. The definition of a pipeline is described in a special [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file. The `codefresh.yml` file can be fetched from the same repository of the source code, from a completely different repository or even defined in-place in the Codefresh pipeline editor. Again, notice that it is possible to have a pipeline that checks out its source code from git repository A, but actually defines its steps in a `codefresh.yml` file that is fetched from git repository B. +* **Pipeline steps**: Each pipeline has a definition that defines the [pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) that are executed each time this pipeline is triggered. The definition of a pipeline is described in a special [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file. The `codefresh.yml` file can be fetched from the same repository as that of the source code, from a completely different repository, or even defined in-place in the Codefresh pipeline editor. Again, notice you can have a pipeline that checks out its source code from Git repository A, but actually defines its steps in a `codefresh.yml` file that is fetched from Git repository B. -* **Triggers**: each pipeline can have zero, one, or more [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/). Codefresh supports several kinds of triggers such as Git, Cron or Docker push triggers. Triggers that happen with Git webhooks can come from the same git repository that contains the git code **OR** any other completely different repository. Triggers are the linking medium between a pipeline and a git repository. You can have a pipeline with many triggers so it will be executed when a code change happens to any of them. +* **Triggers**: A pipeline can have zero, one, or more [triggers]({{site.baseurl}}/docs/pipeline/triggers/). Codefresh supports several kinds of triggers such as Git, Cron, and Docker push triggers. Triggers that happen with Git webhooks can come from the same Git repository that contains the git code, **OR**, a completely different repository. Triggers are the linking medium between a pipeline and a Git repository. You can have a pipeline with multiple triggers to be executed when a code change happens to any of them. With these basic building blocks, you can define many complex workflows. In particular, it is very easy in Codefresh to create a scenario where: @@ -49,7 +49,7 @@ With these basic building blocks, you can define many complex workflows. In part Of course, it also possible to have a simpler scenario where the trigger, the pipeline steps and the source code of the application are all defined for the same GIT repository. -## Creating New Pipelines +## Creating a pipeline You can create new projects by clicking on *Projects* in the left sidebar and then selecting the *New Project* button on the top right corner. A dialog will appear that will ask you for the project name and optional tags that you can use for [access control]({{site.baseurl}}/docs/enterprise/access-control/). @@ -75,7 +75,7 @@ or by copying an existing one from the same project or a completely different pr 1. The main window shows the definition of the current pipeline. The screenshot shows the inline editor but pipelines can also be defined from external files (checked into source control) as explained later. -1. The right part of the window shows extra settings for this pipeline such as [premade steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/) and launch variables/parameters. +1. The right part of the window shows extra settings for this pipeline such as [premade steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), [triggers]({{site.baseurl}}/docs/pipelines/triggers/) and launch variables/parameters. @@ -129,38 +129,37 @@ You can then copy and paste a URL to a raw Codefresh YAML file. This will allow As an example, instead of using `https://github.com/codefresh-contrib/example-voting-app/blob/master/codefresh.yml` you should enter `https://raw.githubusercontent.com/codefresh-contrib/example-voting-app/master/codefresh.yml` -## Pipeline Settings +## Pipeline settings Once you create your pipeline you can also click on the top tab called *Settings* for some extra parameters. ### General -- **Pipeline Name**: the name of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) -- **Pipeline ID**: the ID of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) -> Note that the Pipeline Name and ID are interchangeable when working with the Codefresh CLI -- **Pipeline Description**: a freetext pipeline description -- **Pipeline Tags**: One or more tags used for [access control]({{site.baseurl}}/docs/enterprise/access-control/) -- **Public Build Logs**: If enabled, the builds of this pipeline will be [viewable by users without a Codefresh account]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/#public-build-logs -) -- **Template**: Convert this pipeline to a template (see the next section for details on templates) -- **Badges**: simple images that show you the last [build status]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) +- **Pipeline Name**: The name of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) +- **Pipeline ID**: The ID of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) + > When working with the Codefresh CLI, the Pipeline Name and ID are interchangeable. +- **Pipeline Description**: Freetext pdescription of the pipeline. +- **Pipeline Tags**: One or more tags used for [access control]({{site.baseurl}}/docs/administration/access-control/) +- **Public Build Logs**: If enabled, [users without a Codefresh account]({{site.baseurl}}/docs/pipelines/build-status/#public-build-logs) can view the builds of this pipeline. +- **Template**: Convert this pipeline to a template (see the next section for details on templates). +- **Badges**: Simple images that show you the last [build status]({{site.baseurl}}/docs/pipelines/build-status/). ### Policies -- **Pipeline Concurrency**: the maximum number of concurrent builds (0-14 or unlimited) -- set this when your pipeline has only one trigger +- **Pipeline Concurrency**: The maximum number of concurrent builds (0-14 or unlimited). Set the concurrency when your pipeline has only one trigger. > A Pipeline Concurrency of **0** freezes execution of the pipeline, switching it to maintenance mode. Use this concurrency setting to modify existing pipelines and freeze execution until you complete the changes. -- **Trigger Concurrency**: the maximum number of concurrent builds per trigger (1-15 or unlimited) -- set this when your pipeline has multiple triggers -- **Branch Concurrency**: the maximum number of concurrent builds per branch (1-15 or unlimited) -- set this when your pipeline can build different branches -- **Build Termination**: various toggles for when a build from the pipeline should terminate +- **Trigger Concurrency**: The maximum number of concurrent builds per trigger (1-15 or unlimited). Define the trigger concurrency when your pipeline has multiple triggers. +- **Branch Concurrency**: The maximum number of concurrent builds per branch (1-15 or unlimited). Define this when your pipeline can build different branches. +- **Build Termination**: Options that determine when a build from the pipeline should terminate: - Once a build is created terminate previous builds from the same branch - Once a build is created terminate previous builds only from a specific branch (name matches a regular expression) - Once a build is created, terminate all other running builds - Once a build is terminated, terminate all child builds initiated from it -- **Pending approval volume**: choose what happens with the [pipeline volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) when a pipeline is waiting for [approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) +- **Pending approval volume**: Choose what happens with the [pipeline volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) when a pipeline is waiting for [approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) - Keep the volume available - Discard the volume - Honor the option defined globally in your Codefresh account -- **Pending approval concurrency limit effect**: decide if a build that is pending approval [counts against]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#define-concurrency-limits) the concurrency limits or not +- **Pending approval concurrency limit effect**: Determines if a build that is pending approval [counts against]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#define-concurrency-limits) the concurrency limits or not - Builds in pending approval will **not** be counted when determining the concurrency limit for a pipeline - Builds in pending approval will **be** counted when determining the concurrency limit for a pipeline - Honor the option defined globally in your Codefresh account @@ -185,7 +184,7 @@ Some common scenarios are: For the volume behavior during approvals, notice that if [you keep the volume available]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) on the pipeline while it is waiting for approval it will still count as "running" against your pricing tier limit. -### External Resources +### External resources In a big organization you might have some reusable scripts or other resources (such as Dockerfiles) that you want to use in multiple pipelines. Instead of fetching them manually in freestyle steps you can simply define them as *external resources*. When a pipeline runs, Codefresh will fetch them automatically and once the pipeline starts the files/folders will already be available in the paths that you define. @@ -217,10 +216,11 @@ You can define multiple external resources in a single pipeline. - Small (recommended for 1-2 concurrent steps) - Medium (recommended 3-4 steps) - Large (recommended 5-6 steps) - + ## Using Pipeline Templates -Codefresh also supports the creation of pipeline "templates" which are blueprints for creating new pipelines. To enable the creation of pipelines from templates first visit the global pipeline configuration at [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings) and toggle the *Enable Pipeline Templates* button. +Codefresh also supports the creation of pipeline "templates", which are blueprints for creating new pipelines. +To enable the creation of pipelines from templates first visit the global pipeline configuration at [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings) and toggle the *Enable Pipeline Templates* button. The easiest way to create a new template is by clicking the "3 dots menu" on the pipeline name: @@ -295,12 +295,11 @@ max-width="90%" Pipelines that belong to a project will mention it below their name so it is very easy to understand which pipelines belong to a project and which do not. -## What to read next - -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) -* [YAML Examples]({{site.baseurl}}/docs/yaml-examples/examples/) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +[External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +[YAML Examples]({{site.baseurl}}/docs/yaml-examples/examples/) diff --git a/_docs/pipelines/steps.md b/_docs/pipelines/steps.md index 6cdfb52e..468aef4d 100644 --- a/_docs/pipelines/steps.md +++ b/_docs/pipelines/steps.md @@ -1,57 +1,58 @@ --- -title: "Steps" -description: "Learn the types of Pipeline steps" -group: codefresh-yaml +title: "Steps in pipelines" +description: "Types of steps in Codefresh pipelines" +group: pipelines redirect_from: - /docs/steps/ toc: true --- -Codefresh [pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) are composed of a series of steps. +Codefresh [pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) are composed of a series of steps. -You can create your own pipelines by writing a [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file that describes your pipeline. This file can then be version controlled on its own (pipeline as code). +You can create your own pipelines by writing a [codefresh.yml]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) file that describes your pipeline. This file can then be version controlled on its own (pipeline as code). {% include image.html lightbox="true" -file="/images/codefresh-yaml/stages/complex-pipeline.png" -url="/images/codefresh-yaml/stages/complex-pipeline.png" +file="/images/pipelines/stages/complex-pipeline.png" +url="/images/pipelines/stages/complex-pipeline.png" alt="Pipeline steps" caption="Pipeline steps" max-width="80%" %} -## Built-in steps +## Built-in step types The steps offered by Codefresh are: -* [Git clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) -* [Freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) -* [Build]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) -* [Push]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) -* [Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) -* [Launch test environment]({{site.baseurl}}/docs/codefresh-yaml/steps/launch-composition/) -* [Deploy]({{site.baseurl}}/docs/codefresh-yaml/steps/deploy/) -* [Approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) +* [Git clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) + **Git clone** steps allow you to checkout code in your pipeline from any internal or external repository. Existing accounts that still use repositories instead of [projects]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-concepts) have an implicit clone step in the pipelines. -**Git clone** steps allow you to checkout code in your pipeline from any internal or external repository. Existing accounts that still use repositories instead of [projects]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-concepts) have an implicit clone step in the pipelines. - -**Freestyle** steps are the cornerstone of Codefresh pipelines. They allow you to run any command within the context of a Docker container. A lot of Codefresh optimizations such as the [shared docker volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are designed specifically for freestyle steps. +* [Freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/) + **Freestyle** steps are the cornerstone of Codefresh pipelines. They allow you to run any command within the context of a Docker container. A lot of Codefresh optimizations such as the [shared docker volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are designed specifically for freestyle steps. Freestyle steps are a secure replacement for `docker run` commands. -**Build** steps are the main way where you get access to the Docker daemon (Docker as a service) in Codefresh pipelines. Build steps take as input any Dockerfile and run it on the cloud in a similar manner to what you do on your workstation. Build steps automatically push the result to the default Docker registry of your account (no need for docker login commands). Codefresh also comes with a global Docker cache that automatically gets attached to all build nodes. Build steps are a secure replacement for `docker build` commands. +* [Build]({{site.baseurl}}/docs/pipelines/steps/build/) + **Build** steps are the main way where you get access to the Docker daemon (Docker as a service) in Codefresh pipelines. Build steps take as input any Dockerfile and run it on the cloud in a similar manner to what you do on your workstation. Build steps automatically push the result to the default Docker registry of your account (no need for docker login commands). Codefresh also comes with a global Docker cache that automatically gets attached to all build nodes. Build steps are a secure replacement for `docker build` commands. + +* [Push]({{site.baseurl}}/docs/pipelines/steps/push/) +**Push** steps allow you to push and tag your docker images (created by the build step) in any [external Docker registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). Push steps are *not* needed at all if you work with only the internal Codefresh registry. Push steps are a secure replacement for the `docker tag` and `docker push` commands. + +* [Composition]({{site.baseurl}}/docs/pipelines/steps/composition/) + **Composition** steps allow you to run multiple services together in the Codefresh infrastructure and execute unit tests or other commands against them. They are discarded once a pipeline finishes. Composition steps are a secure replacement for `docker-compose` definitions. -**Push** steps allow you to push and tag your docker images (created by the build step) in any [external Docker registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). Push steps are *not* needed at all if you work with only the internal Codefresh registry. Push steps are a secure replacement for the `docker tag` and `docker push` commands. +* [Launch test environment]({{site.baseurl}}/docs/pipelines/steps/launch-composition/) + **Launch test environment** steps behave similar to compositions, but they persist after the pipeline ends. This is a great way to create preview environment from your pull requests and send to colleagues. -**Composition** steps allow you to run multiple services together in the Codefresh infrastructure and execute unit tests or other commands against them. They are discarded once a pipeline finishes. Composition steps are a secure replacement for `docker-compose` definitions. +* [Deploy]({{site.baseurl}}/docs/pipelines/steps/deploy/) + **Deploy steps** allow you to [perform Kubernetes deployments]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes/) in a declarative manner. They embody the Continuous Deployment aspect of Codefresh. -**Launch test environment** steps behave similar to compositions, but they persist after the pipeline ends. This is a great way to create preview environment from your pull requests and send to colleagues. +* [Approval]({{site.baseurl}}/docs/pipelines/steps/approval/) + **Approval steps** allow you to pause pipelines and wait for human intervention before resuming. They allow you to embrace the concepts of Continuous Delivery. -**Deploy steps** allow you to [perform Kubernetes deployments]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes/) in a declarative manner. They embody the Continuous Deployment aspect of Codefresh. -**Approval steps** allow you to pause pipelines and wait for human intervention before resuming. They allow you to embrace the concepts of Continuous Delivery. ->Note that Codefresh also supports [parallel workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) as well as running pipelines [locally on your workstation]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/). +>Codefresh also supports [parallel workflows]({{site.baseurl}}/docs/pipelines/advanced-workflows/), as well as running pipelines [locally on your workstation]({{site.baseurl}}/docs/pipelines/running-pipelines-locally/). ## Step directory @@ -85,8 +86,8 @@ When you create a pipeline, you will have access to two categories of steps: {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/choose-step.png" -url="/images/codefresh-yaml/steps/choose-step.png" +file="/images/pipelines/steps/choose-step.png" +url="/images/pipelines/steps/choose-step.png" alt="Choosing a custom step" caption="Choosing a custom step" max-width="60%" @@ -94,13 +95,13 @@ max-width="60%" To use a step, first click on the pipeline section where you want to insert the step. You will get a new dialog with all the details of the step along with a live preview of the exact -[yaml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) that will be inserted in your pipeline. +[yaml]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) that will be inserted in your pipeline. For all steps you can define: * The title of the text (which will also be visible in the pipeline UI) * A freetext description -* The [stage]({{site.baseurl}}/docs/codefresh-yaml/stages/) that will contain the step +* The [stage]({{site.baseurl}}/docs/pipelines/stages/) that will contain the step The rest of the fields are specific to each step. See the documentation of each step in order to understand what each field should contain. There are fields for each step that are marked as required and are essential for the step to work. These are marked with an asterisk. @@ -134,7 +135,7 @@ We suggest that you start with custom freestyle steps first and only create type ### Creating a custom freestyle step -As an example let's say that you need to use the [JFrog CLI](https://jfrog.com/getcli/) in a pipeline in order to interact with a Artifactory or Bintray. JFrog does not offer any Docker image that contains the CLI and you already know that all Codefresh steps [are actually Docker images]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). +As an example let's say that you need to use the [JFrog CLI](https://jfrog.com/getcli/) in a pipeline in order to interact with a Artifactory or Bintray. JFrog does not offer any Docker image that contains the CLI and you already know that all Codefresh steps [are actually Docker images]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/). Therefore you can easily package the CLI into a Docker image and then make it available to any Codefresh pipeline that wishes to use it. First you create [a Dockerfile](https://github.com/kostis-codefresh/step-examples/blob/master/jfrog-cli-wrapper/Dockerfile) that packages the CLI @@ -179,8 +180,8 @@ Once the Dockerfile is ready, you need to push it to Dockerhub. You can either d {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/create-custom-step.png" -url="/images/codefresh-yaml/steps/create-custom-step.png" +file="/images/pipelines/steps/create-custom-step.png" +url="/images/pipelines/steps/create-custom-step.png" alt="Creating a custom freestyle step" caption="Creating a custom freestyle step" max-width="80%" @@ -391,8 +392,8 @@ You will now be able to see the new versions of your plugin in the step marketpl {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/step-versions.png" -url="/images/codefresh-yaml/steps/step-versions.png" +file="/images/pipelines/steps/step-versions.png" +url="/images/pipelines/steps/step-versions.png" alt="Different step versions" caption="Different step versions" max-width="60%" @@ -520,7 +521,7 @@ be passed by the plugin user to specify the folder that contains the `package.js The plugin implementation is specified in the `steps` sections. We use the standard [Node Docker image](https://hub.docker.com/_/node) to read the version from the `package.json` file. Notice how we convert the plugin argument to an environment variable called `WORK_DIR` -By default all plugins start with the Codefresh volume at `/codefresh/volume` as a working folder. So with the `cd` command we enter the project folder (which we assume was checked out in a previous pipeline step). Once the version is read it is made available to all the other pipeline steps with the [cf_export command]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command). +By default all plugins start with the Codefresh volume at `/codefresh/volume` as a working folder. So with the `cd` command we enter the project folder (which we assume was checked out in a previous pipeline step). Once the version is read it is made available to all the other pipeline steps with the [cf_export command]({{site.baseurl}}/docs/pipelines/variables/#using-cf_export-command). We now insert our plugin in the marketplace with the following command: @@ -561,8 +562,8 @@ This is a very simple pipeline that checks out a NodeJS project and uses our plu {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/input-parameters.png" -url="/images/codefresh-yaml/steps/input-parameters.png" +file="/images/pipelines/steps/input-parameters.png" +url="/images/pipelines/steps/input-parameters.png" alt="Step input parameters" caption="Step input parameters" max-width="60%" @@ -573,8 +574,8 @@ The input parameter is also shown as required in the marketplace. {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/input-parameters-definition.png" -url="/images/codefresh-yaml/steps/input-parameters-definition.png" +file="/images/pipelines/steps/input-parameters-definition.png" +url="/images/pipelines/steps/input-parameters-definition.png" alt="Input parameters on marketplace" caption="Input parameters on marketplace" max-width="40%" @@ -699,8 +700,8 @@ The output parameters of the step are now shown in the marketplace so consumers {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/output-parameters-definition.png" -url="/images/codefresh-yaml/steps/output-parameters-definition.png" +file="/images/pipelines/steps/output-parameters-definition.png" +url="/images/pipelines/steps/output-parameters-definition.png" alt="Output parameters on marketplace" caption="Output parameters on marketplace" max-width="40%" @@ -775,8 +776,8 @@ We now have a custom Docker image that contains our executable. If we want other {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/create-plugin-image.png" -url="/images/codefresh-yaml/steps/create-plugin-image.png" +file="/images/pipelines/steps/create-plugin-image.png" +url="/images/pipelines/steps/create-plugin-image.png" alt="Building a public Docker image" caption="Building a public Docker image" max-width="60%" @@ -900,8 +901,8 @@ If you look at the plugin entry in the marketplace you will see both input (the {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/plugin-parameters.png" -url="/images/codefresh-yaml/steps/plugin-parameters.png" +file="/images/pipelines/steps/plugin-parameters.png" +url="/images/pipelines/steps/plugin-parameters.png" alt="Input and output parameters" caption="Input and output parameters" max-width="60%" @@ -912,8 +913,8 @@ The plugin is now ready to be used in a pipeline: {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/plugin-usage.png" -url="/images/codefresh-yaml/steps/plugin-usage.png" +file="/images/pipelines/steps/plugin-usage.png" +url="/images/pipelines/steps/plugin-usage.png" alt="Plugin usage" caption="Plugin usage" max-width="60%" @@ -951,7 +952,7 @@ This was a trivial example, but it clearly demonstrates how a custom step commun ### Exporting parameters manually inside a plugin -Normally, in a pipeline you can either use the [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) command or write directly to the [/codefresh/volume/env_vars_to_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#directly-writing-to-the-file) file. +Normally, in a pipeline you can either use the [cf_export]({{site.baseurl}}/docs/pipelines/variables/#using-cf_export-command) command or write directly to the [/codefresh/volume/env_vars_to_export]({{site.baseurl}}/docs/pipelines/variables/#directly-writing-to-the-file) file. However, inside a plugin you can also use the `/meta/env_vars_to_export` file that has the same semantics, but is used for exporting variables in the same scope as the plugin only. @@ -1193,8 +1194,8 @@ The end result is that with a single step you can checkout many projects. Checki {% include image.html lightbox="true" -file="/images/codefresh-yaml/steps/multi-checkout.png" -url="/images/codefresh-yaml/steps/multi-checkout.png" +file="/images/pipelines/steps/multi-checkout.png" +url="/images/pipelines/steps/multi-checkout.png" alt="Checking out multiple Git repositories in a single step" caption="Checking out multiple Git repositories in a single step" max-width="60%" @@ -1204,20 +1205,20 @@ This was a contrived example to demonstrate how you can use templates in the Cod ### Limitations of custom plugins -[Parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) are not supported inside custom steps. +[Parallel steps]({{site.baseurl}}/docs/pipelines/advanced-workflows/) are not supported inside custom steps. -Within a custom step, the [fail_fast field]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#execution-flow) does not work. Use the `failFast` field instead. +Within a custom step, the [fail_fast field]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/#execution-flow) does not work. Use the `failFast` field instead. -Custom steps are not compatible with [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/). +Custom steps are not compatible with [service containers]({{site.baseurl}}/docs/pipelines/service-containers/). More specifically: - * If you have a [service container in the pipeline-level]({{site.baseurl}}/docs/codefresh-yaml/service-containers/#running-services-for-the-duration-of-the-pipeline), steps inside the custom plugin will not be able to access it + * If you have a [service container in the pipeline-level]({{site.baseurl}}/docs/pipelines/service-containers/#running-services-for-the-duration-of-the-pipeline), steps inside the custom plugin will not be able to access it * If you try to attach a service container to a custom plugin, the plugin will fail when executed * If you try to define a custom plugin where a step inside it has a service container attached, the custom plugin will fail when executed -## What to read next +## Related articles +[Introduction to Pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) +[Build step]({{site.baseurl}}/docs/pipelines/steps/build/) +[Push step]({{site.baseurl}}/docs/pipelines/steps/push/) -* [Introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) -* [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) -* [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) -* [Push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) diff --git a/_docs/pipelines/steps/approval.md b/_docs/pipelines/steps/approval.md index 1d528656..dee497d2 100644 --- a/_docs/pipelines/steps/approval.md +++ b/_docs/pipelines/steps/approval.md @@ -131,9 +131,9 @@ For more details on access control and users see also the [access control page]( ## Keeping the Shared Volume after an Approval -As soon as a pipeline starts waiting for an approval, all contents of the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are lost. Once the pipeline continues running all files that were created manually inside the volume are not available any more. +As soon as a pipeline starts waiting for an approval, all contents of the [shared Codefresh volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) are lost. Once the pipeline continues running all files that were created manually inside the volume are not available any more. -If you want to keep any temporary files that were there before the approval, you need to enable the respective policy in your [pipeline settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#policies). +If you want to keep any temporary files that were there before the approval, you need to enable the respective policy in your [pipeline settings]({{site.baseurl}}/docs/pipelines/pipelines/#policies). You can either set this option differently per pipeline, or globally in your account at your [account settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings). @@ -149,7 +149,7 @@ max-width="90%" >Notice that if you do decide to keep the volume after an approval, the pipeline will still count as "running" against your pricing plan (if you use the SAAS version of Codefresh). If you don't keep the volume, the pipeline is stopped/paused while it is waiting for approval and doesn't count against your pricing plan. We advise you to keep the volume only for pipelines that really need this capability. ->Notice also that you if you use the [Hybrid version]({{site.baseurl}}/docs/administration/behind-the-firewall/) of Codefresh and your [Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) is setup with local volumes, then the volume will only be present if the dind pod +>Notice also that you if you use the [Codefresh Runner]({{site.baseurl}}/docs/reference/behind-the-firewall/) and your [Runner]({{site.baseurl}}/docs/installation/codefresh-runner/) is setup with local volumes, then the volume will only be present if the dind pod is scheduled in the same node once the pipeline resumes. Otherwise the volume will not be reused. ## Controlling the Rejection Behavior @@ -175,7 +175,7 @@ In this case you can also read the approval result and make the pipeline work di ## Getting the Approval Result -As also explained in [step dependencies]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#custom-steps-dependencies) all steps in the Codefresh pipeline belong to a global object +As also explained in [step dependencies]({{site.baseurl}}/docs/pipelines/advanced-workflows/#custom-steps-dependencies) all steps in the Codefresh pipeline belong to a global object called `steps` (indexed by name). You can read the `result` property for an approval step to see if it was approved or rejected. Here is an example: @@ -335,16 +335,14 @@ max-width="50%" %} Also, if you run a pipeline manually that includes an approval step you should check -the "Report notification of pipeline execution" checkbox as explained in [Monitoring Pipelines]( -{{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/#monitoring-pipelines-outside-the-codefresh-ui). +the "Report notification of pipeline execution" checkbox as explained in [Monitoring Pipelines]({{site.baseurl}}/docs/pipelines/monitoring-pipelines/#monitoring-pipelines-outside-the-codefresh-ui). -## What to read next - -- [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) -- [Advanced Workflows ]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) -- [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) -- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +## Related articles +[Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/) +[Advanced Workflows ]({{site.baseurl}}/docs/pipelines/advanced-workflows/) +[Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) diff --git a/_docs/pipelines/steps/build.md b/_docs/pipelines/steps/build.md index e432275c..26fdb2fb 100644 --- a/_docs/pipelines/steps/build.md +++ b/_docs/pipelines/steps/build.md @@ -1,7 +1,7 @@ --- title: "Build" description: "Building Docker images in Codefresh pipelines" -group: codefresh-yaml +group: pipelines sub_group: steps redirect_from: - /docs/build-1/ @@ -90,11 +90,11 @@ step_name: | `build_arguments` | A set of [Docker build arguments](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg) to pass to the build process. | Optional | | `target` | target stage in a multistage build (build will run until this stage) | Optional | | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions that need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | +| `when` | Define a set of conditions that need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | | `metadata` | Annotate the built image with [key-value metadata]({{site.baseurl}}/docs/docker-registries/metadata-annotations/). | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/). | Optional | | `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | -| `buildkit` | Set to `true` to enable [Buildkit]({{site.baseurl}}/docs/codefresh-yaml/steps/build/#buildkit-support) and all of its enhancements | Optional | +| `buildkit` | Set to `true` to enable [Buildkit]({{site.baseurl}}/docs/pipelines/steps/build/#buildkit-support) and all of its enhancements | Optional | **Exported resources:** - Working Directory @@ -162,7 +162,7 @@ steps: registry: my-registry {% endhighlight %} -Build two images in two different folders using [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) as tags. +Build two images in two different folders using [Codefresh variables]({{site.baseurl}}/docs/pipelines/variables/) as tags. `codefresh.yml` {% highlight yaml %} @@ -186,7 +186,7 @@ steps: {% endraw %} {% endhighlight %} -It also possible to build Docker images in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) for faster builds. +It also possible to build Docker images in [parallel]({{site.baseurl}}/docs/pipelines/advanced-workflows/) for faster builds. ### Inline Dockerfile @@ -227,7 +227,7 @@ Use this technique only as a last resort. It is better if the Dockerfile exists All images built successfully with the build step, will be automatically pushed to the default Docker registry in your account. This behavior is completely automatic and happens without any extra configuration on your part. If you want to disable this then add the `disable_push` property in your build step. ->Notice that the [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) in Codefresh is optional and is only needed if you want to push to [external Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). +>Notice that the [push step]({{site.baseurl}}/docs/pipelines/steps/push/) in Codefresh is optional and is only needed if you want to push to [external Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). {% include image.html @@ -346,7 +346,7 @@ You might want to use an environment variable to store and retrieve a ssh key. T tr '\n' ',' < /path/to/id_rsa ``` -Copy the output and place it an [environment variable]({{site.baseurl}}/docs/codefresh-yaml/variables/#user-provided-variables). To make the SSH key availabe to the build step, you can write it to the codefresh volume: +Copy the output and place it an [environment variable]({{site.baseurl}}/docs/pipelines/variables/#user-provided-variables). To make the SSH key availabe to the build step, you can write it to the codefresh volume: `codefresh.yml` {% highlight yaml %} {% raw %} @@ -374,7 +374,6 @@ You can combine all options (`ssh`, `progress`, `secrets`) in a single build ste -## What to read next - -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline Steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) diff --git a/_docs/pipelines/steps/composition.md b/_docs/pipelines/steps/composition.md index 75e75899..40764e68 100644 --- a/_docs/pipelines/steps/composition.md +++ b/_docs/pipelines/steps/composition.md @@ -1,7 +1,7 @@ --- -title: "Composition" +title: "Composition step" description: "Run a Docker container with its dependencies inside a pipeline" -group: codefresh-yaml +group: pipelines sub_group: steps redirect_from: - /docs/composition-1/ @@ -102,8 +102,8 @@ The following describes the fields available in a step of type `composition` | `volumes` (service level) | Extra volumes for individual services. Used for transferring information between your steps. Explained in detail later in this page. | Optional | | `composition_variables` | A set of environment variables to substitute in the composition. Notice that these variables are docker-compose variables and **NOT** environment variables | Optional | | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/). | Optional | | `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | ## Composition versus Composition Candidates @@ -290,7 +290,7 @@ By default, the services of a composition run in a completely isolated manner. T * Preloading a database with a data script found in Git * Running integration tests and then using their [results for reporting]({{site.baseurl}}/docs/testing/test-reports/) -The Codefresh [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automatically mounted in [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) but **NOT** in compositions. You have to mount it yourself if you use that functionality. +The Codefresh [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automatically mounted in [freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/) but **NOT** in compositions. You have to mount it yourself if you use that functionality. Here is an example where the shared volume is mounted in a composition -- {% raw %}`'${{CF_VOLUME_NAME}}:${{CF_VOLUME_PATH}}'`{% endraw %} is listed under `volumes`: @@ -426,9 +426,9 @@ run_tests: In the above example, both `composition` and `composition_candidates` define a service named `test_service`. After merging these definitions, `test_service` will maintain the `command` that was defined in the original composition but will refer to the image built by the step named `build_step`. -## What to read next +## Related articles +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Variables]({{site.baseurl}}/docs/pipelines/variables/) +[Introduction to pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Introduction to pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) -* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) diff --git a/_docs/pipelines/steps/deploy.md b/_docs/pipelines/steps/deploy.md index a3a2fe0e..6ad0a4e38 100644 --- a/_docs/pipelines/steps/deploy.md +++ b/_docs/pipelines/steps/deploy.md @@ -82,8 +82,8 @@ with the `candidate` field (otherwise Codefresh will just reuse the docker image | `timeout` | Seconds to wait for the deployment to be completed. Default is 120 seconds | Default | | `candidate` | Docker image that will be deployed. Only valid if `service` is defined. Should contain `image` and name of registry as it appears in the [registry integration page]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). | Optional | | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/piplines/post-step-operations/). | Optional | | `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | ## Examples @@ -176,9 +176,10 @@ If you find the deploy step limited, feel free to look at the other deployment o * [Custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) * [Helm]({{site.baseurl}}/docs/getting-started/helm-quick-start-guide/) -## What to read next -- [Kubernetes Quick start guide]({{site.baseurl}}/docs/getting-started/deployment-to-kubernetes-quick-start-guide/) -- [Manage your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/) -- [Install HELM chart using Codefresh pipeline]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) +## Related articles +[Kubernetes Quick start guide]({{site.baseurl}}/docs/getting-started/deployment-to-kubernetes-quick-start-guide/) +[Manage your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/) +[Install HELM chart using Codefresh pipeline]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) + diff --git a/_docs/pipelines/steps/freestyle.md b/_docs/pipelines/steps/freestyle.md index 8d0723fa..4610bd95 100644 --- a/_docs/pipelines/steps/freestyle.md +++ b/_docs/pipelines/steps/freestyle.md @@ -35,7 +35,7 @@ CollectAllMyDeps: Select an image to start a container, then you can specify a working directory, and commands. If you do not specify a working directory or commands, the step runs the organic commands specified by the image. -In all freestyle steps Codefresh automatically [uses a shared docker volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that contains your git source code. +In all freestyle steps Codefresh automatically [uses a shared docker volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that contains your git source code. ## Usage @@ -84,7 +84,7 @@ step_name: | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `title` | The free-text display name of the step. | Optional | | `description` | A basic, free-text description of the step. | Optional | -| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/pipelines/stages/) for more information. | Optional | | `image` | The image from which the executable container is created. It can be an explicit ID of a Docker image, or a variable that references a **Build** or **Push** step. | Required | | `working_directory` | The directory from which the commands are executed. It can be an explicit path in the container's file system, or a variable that references another step. The default `working_directory` is the cloned repository directory and not the working directory specified by the image. If you need to use the default working directory of the image use `IMAGE_WORK_DIR`. | Default | | `commands` | One or more commands to execute in a shell in the container, as array of strings. | Optional | @@ -95,8 +95,8 @@ step_name: | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | | `registry_context` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | | `volumes` | One or more volumes for the container. All volumes must be mounted from the existing shared volume (see details below) |Optional -| `when` | Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `when` | Define a set of conditions that need to be satisfied in order to execute this step. You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/). | Optional | | `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | **Exported resources:** @@ -104,7 +104,7 @@ step_name: ## Examples -Here are some full pipelines with freestyle steps. Notice that in all cases the pipelines are connected to [git repositories]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-creation-modes) +Here are some full pipelines with freestyle steps. Notice that in all cases the pipelines are connected to [git repositories]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-creation-modes) so the source code is already checked out and available to all pipeline steps. **Creating a [JAR file]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/):** @@ -173,7 +173,7 @@ steps: ## Dynamic freestyle steps Codefresh has the unique ability to allow you to run freestyle steps in the context of a docker image -created on the same pipeline. This means that you can dynamically [create docker images]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) on demand within the pipeline +created on the same pipeline. This means that you can dynamically [create docker images]({{site.baseurl}}/docs/pipelines/steps/build/) on demand within the pipeline that needs them. Creating a custom docker image with extra tools (Terraform and Ansible) @@ -197,7 +197,7 @@ steps: {% endraw %} {% endhighlight %} -Here the `UseMyCustomImage` freestyle step is running in the [context]({{site.baseurl}}/docs/codefresh-yaml/variables/#context-related-variables) of the Docker image that was created in the previous step. +Here the `UseMyCustomImage` freestyle step is running in the [context]({{site.baseurl}}/docs/pipelines/variables/#context-related-variables) of the Docker image that was created in the previous step. In fact, a very common pattern that you will see in Codefresh pipelines is the executions of [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) in the image that was created in a build step: `codefresh.yml` @@ -248,7 +248,7 @@ entry_point: When you use the `commands` field, it will override the container original `entry_point` and will execute the commands in a shell inside the container. The provided commands are concatenated into a single command using the shell's `;` operator, and are run using the default shell `/bin/sh` as an entry point. -Additional settings that are set only when using commands are `set -e`, and the [`cf_export`]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) utility. +Additional settings that are set only when using commands are `set -e`, and the [`cf_export`]({{site.baseurl}}/docs/pipelines/variables/#using-cf_export-command) utility. > Using complex commands in the freestyle step requires use of [YAML block scalars](http://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines). @@ -275,9 +275,9 @@ commands: ## Custom volumes -If you are familiar with [Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) you should know that all freestyle steps automatically share a [volume](https://docs.docker.com/storage/) mounted at `/codefresh/volume` which can be used to transfer data (e.g. dependencies and test results) from each step to the next. +If you are familiar with [Codefresh pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) you should know that all freestyle steps automatically share a [volume](https://docs.docker.com/storage/) mounted at `/codefresh/volume` which can be used to transfer data (e.g. dependencies and test results) from each step to the next. -**This volume is automatically mounted by Codefresh and needs no configuration at all**. All you have to do to access it, is read/write the `/codefresh/volume` folder from your application. This folder also [includes by default the source code]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) of the git repository connected to the pipeline (at the `/codefresh/volume/` subfolder) +**This volume is automatically mounted by Codefresh and needs no configuration at all**. All you have to do to access it, is read/write the `/codefresh/volume` folder from your application. This folder also [includes by default the source code]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#cloning-the-source-code) of the git repository connected to the pipeline (at the `/codefresh/volume/` subfolder) You can use the `volumes` property to create your own custom volumes that can be mounted in different folders. **For security reasons however all source volume data (i.e. the "host" folder) still needs to be bound with `/codefresh/volume` or any of its subdirectories**: @@ -345,9 +345,8 @@ max-width="80%" %} -## What to read next - -* [Introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline Steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +## Related articles +[Introduction to Pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) diff --git a/_docs/pipelines/steps/git-clone.md b/_docs/pipelines/steps/git-clone.md index fa1e4084..628841a6 100644 --- a/_docs/pipelines/steps/git-clone.md +++ b/_docs/pipelines/steps/git-clone.md @@ -1,7 +1,7 @@ --- title: "Git-Clone" description: "Checkout code in your pipelines" -group: codefresh-yaml +group: pipelines sub_group: steps redirect_from: - /docs/git-clone/ @@ -9,7 +9,7 @@ toc: true --- Clones a Git repository to the filesystem. -A pipeline can have any number of git clone steps (even none). You can checkout code from any private or public repository. Cloning a repository is not constrained to the trigger of a pipeline. You can trigger a pipeline from a commit that happened on Git repository A while the pipeline is checking out code from Git Repository B. +A pipeline can have any number of Git clone steps (even none). You can checkout code from any private or public repository. Cloning a repository is not constrained to the trigger of a pipeline. You can trigger a pipeline from a commit that happened on Git repository A while the pipeline is checking out code from Git Repository B. >Notice that if you are an existing customer before May 2019, Codefresh will automatically checkout the code from a [connected git repository]({{site.baseurl}}/docs/integrations/git-providers/) when a pipeline is created on that repository. In this case an implicit git clone step is included in your pipeline. You can still override it with your own git clone step as explained in this page @@ -50,7 +50,7 @@ step_name: | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `title` | The free-text display name of the step. | Optional | | `description` | A basic, free-text description of the step. | Optional | -| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/pipelines/stages/) for more information. | Optional | | `working_directory` | The directory to which the repository is cloned. It can be an explicit path in the container's file system, or a variable that references another step. The default value is {% raw %}`${{main_clone}}`{% endraw %}, but note that the default will only be used if you name your step `main_clone`. See the example on [working inside the cloned directory]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/#working-inside-the-cloned-directory) for more information. | Default | | `git` | The name of the [git integration]({{site.baseurl}}/docs/integrations/git-providers/) you want to use. If left empty, Codefresh will attempt to use the git provider that was used during account sign-up. Note that this might have unexpected results if you are changing your Git integrations.| Required| | `repo` | path of the repository without the domain name in the form of `my_username/my_repo` | Required | @@ -75,7 +75,7 @@ The easiest way to use a git clone step is to use your default git provider as c Here is an example of a pipeline that will automatically check out the repository that triggered it (i.e. a commit happened on that repository). ->Notice that the name of the clone step is `main_clone`. This will automatically set the working directory of all other steps that follow it **inside** the folder of the project that was checked out. This only applies to [built-in]({{site.baseurl}}/docs/codefresh-yaml/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/codefresh-yaml/steps/#creating-a-typed-codefresh-plugin). This is normally what you want for a pipeline that only checks out a single project. If you use any other name apart from `main_clone` the working directory for all subsequent steps will not be affected and it will default on the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) which is the [parent folder]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) of checkouts. +>Notice that the name of the clone step is `main_clone`. This will automatically set the working directory of all other steps that follow it **inside** the folder of the project that was checked out. This only applies to [built-in]({{site.baseurl}}/docs/pipelines/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/pipelines/steps/#creating-a-typed-codefresh-plugin). This is normally what you want for a pipeline that only checks out a single project. If you use any other name apart from `main_clone` the working directory for all subsequent steps will not be affected and it will default on the [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) which is the [parent folder]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#cloning-the-source-code) of checkouts. @@ -98,7 +98,7 @@ steps: {% endraw %} {% endhighlight %} -The CF values will be automatically filled by Codefresh from the git trigger. See the [variables page]({{site.baseurl}}/docs/codefresh-yaml/variables/) for more details. +The CF values will be automatically filled by Codefresh from the git trigger. See the [variables page]({{site.baseurl}}/docs/pipelines/variables/) for more details. ## Choosing a specific git provider (project-based pipeline) @@ -182,8 +182,8 @@ steps: ## Checkout code using the Codefresh Runner -If you are using the [Hybrid version]({{site.baseurl}}/docs/enterprise/installation-security/#hybrid-installation) of Codefresh and a have a [Codefresh runner]({{site.baseurl}}/docs/enterprise/codefresh-runner/) installed, you need to use -the fully qualified path of the git repository: +If you are using the [Codefresh runner]({{site.baseurl}}/docs/installation/codefresh-runner/), you need to use +the fully qualified path of the Git repository: `codefresh.yml` {% highlight yaml %} @@ -204,14 +204,14 @@ steps: {% endraw %} {% endhighlight %} -More details can be found in the [private Git instructions page]({{site.baseurl}}/docs/enterprise/behind-the-firewall/#checking-out-code-from-a-private-git-repository). +More details can be found in the [private Git instructions page]({{site.baseurl}}/docs/reference/behind-the-firewall/#checking-out-code-from-a-private-git-repository). -## Checking multiple git repositories +## Checking out multiple Git repositories It is very easy to checkout additional repositories in a single pipeline by adding more `git-clone` steps. In that case you should use different names for the steps (instead of `main_clone`) as this will make the working -folder for all steps the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps). +folder for all steps the [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps). `codefresh.yml` {% highlight yaml %} @@ -359,7 +359,7 @@ This pipeline does the following: ## Use an SSH key with Git -It is also possible to use an SSH key with git. When [creating your pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) add your SSH key as an encrypted +It is also possible to use an SSH key with git. When [creating your pipeline]({{site.baseurl}}/docs/pipelines/pipelines/) add your SSH key as an encrypted environment variable after processing it with `tr`: ``` @@ -390,7 +390,7 @@ steps: ## Using Git behind a proxy -If you use the [Codefresh Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) and need to use a network proxy in your clone step you need to set the [variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) `HTTP_PROXY` and/or `HTTPS_PROXY` in the pipeline +If you use the [Codefresh Runner]({{site.baseurl}}/docs/installation/codefresh-runner/) and need to use a network proxy in your clone step you need to set the [variables]({{site.baseurl}}/docs/pipelines/variables/) `HTTP_PROXY` and/or `HTTPS_PROXY` in the pipeline and then activate the property `use_proxy: true` in the clone step. Example: `codefresh.yml` @@ -421,16 +421,16 @@ caption="Pipeline variable" max-width="40%" %} -For more details see the [behind the firewall page]({{site.baseurl}}/docs/administration/behind-the-firewall/). +For more details see the [behind the firewall page]({{site.baseurl}}/docs/installation/behind-the-firewall/). -## What to read next +## Related articles +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Git integrations]({{site.baseurl}}/docs/integrations/git-providers/) +[YAML steps]({{site.baseurl}}/docs/pipelines/steps/) +[Git Checkout Examples]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) +[Custom Git Commands]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout-custom/) -- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -- [Git integrations]({{site.baseurl}}/docs/integrations/git-providers/) -- [YAML steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -- [Git Checkout Examples]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) -- [Custom Git Commands]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout-custom/) diff --git a/_docs/pipelines/steps/launch-composition.md b/_docs/pipelines/steps/launch-composition.md index e2bd5d48..a3bce2d5 100644 --- a/_docs/pipelines/steps/launch-composition.md +++ b/_docs/pipelines/steps/launch-composition.md @@ -1,17 +1,17 @@ --- title: "Launch-Composition" description: "Create a test environment with its dependencies in Codefresh infrastructure" -group: codefresh-yaml +group: pipelines sub_group: steps redirect_from: - /docs/launch-composition-2/ - /docs/codefresh-yaml/steps/launch-composition-2/ toc: true --- -The launch composition step provides the ability to launch long term running environments that can live outside the context of a running pipeline. +The Launch Composition step provides the ability to launch long term running environments that can live outside the context of a running pipeline. You can use this step to automate your test environment creation through a codefresh.yml file instead of manually launching an environment from the UI. ->Note that "launch-composition" creates a permanent test environment that keeps running even after a pipeline has finished. If you just want temporary test environments that run *only while* a pipeline is running, see [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) and the documentation page for [integration tests]({{site.baseurl}}/docs/testing/integration-tests/). +>Note that "launch-composition" creates a permanent test environment that keeps running even after a pipeline has finished. If you just want temporary test environments that run *only while* a pipeline is running, see [service containers]({{site.baseurl}}/docs/pipelines/service-containers/) and the documentation page for [integration tests]({{site.baseurl}}/docs/testing/integration-tests/). ## Usage @@ -74,20 +74,19 @@ step_name: | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `title` | The free-text display name of the step. | Optional | | `description` | A basic, free-text description of the step. | Optional | -| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/pipelines/stages/) for more information. | Optional | | `working_directory` | The directory in which to search for the composition file. It can be an explicit path in the container's file system, or a variable that references another step.
The default is {% raw %}`${{main_clone}}`{% endraw %}. | Default | | `composition` | The composition you want to run. It can be an inline YAML definition, a path to a composition file on the file system, or the logical name of a composition stored in the Codefresh system. | Required | | `environment_name` | The environment name that will be given. In case a previous environment exists with the same name, it will first be terminated. The default value will the be the name/path provided in the 'composition' field. | Default | | `composition_variables` | A set of environment variables to substitute in the composition. | Optional | | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [[Conditional Execution of Steps]({{ site.baseurl }}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{ site.baseurl }}/docs/codefresh-yaml/post-step-operations/). | Optional | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [[Conditional Execution of Steps]({{ site.baseurl }}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{ site.baseurl }}/docs/pipelines/post-step-operations/). | Optional | | entry_point | The name of main service | Optional | | `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | -## What to read next - -* [Preview environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) -* [Launch Composition example]({{site.baseurl}}/docs/yaml-examples/examples/launch-composition/) -* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) -* [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) \ No newline at end of file +## Related articles +[Preview environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) +[Launch Composition example]({{site.baseurl}}/docs/yaml-examples/examples/launch-composition/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +[Service Containers]({{site.baseurl}}/docs/pipelines/service-containers/) \ No newline at end of file diff --git a/_docs/pipelines/steps/push.md b/_docs/pipelines/steps/push.md index 2f5356ea..699f0200 100644 --- a/_docs/pipelines/steps/push.md +++ b/_docs/pipelines/steps/push.md @@ -1,7 +1,7 @@ --- title: "Push step" description: "Pushing Docker images from your pipeline" -group: codefresh-yaml +group: pipelines sub_group: steps redirect_from: - /docs/push-1/ @@ -53,7 +53,7 @@ step_name: | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | `title` | The free-text display name of the step. | Optional | | `description` | A basic, free-text description of the step. | Optional | -| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) for more information. | Optional | +| `stage` | Parent group of this step. See [using stages]({{site.baseurl}}/docs/pipelines/stages/) for more information. | Optional | | `candidate` | The identifier of the image to push to the remote Docker registry. It can be an explicit identifier of an image to push, or a variable that references a `Build` step. | Required | | `tag` | The tag under which to push the image. Use either this or `tags`.
The default is `latest`. | Default | | `region` | Relevant only for [Amazon ECR]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) integrations using either service accounts or explicit credentials. The names of the regions for which to perform cross-region replication. The names of the source region and the destination region name must be defined in separate steps. | Optional | @@ -65,9 +65,9 @@ step_name: | `registry` | The registry logical name of one of the inserted registries from the integration view.
The default value will be your default registry [if you have more than one]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). | Default | | `registry_context` | Advanced property for resolving Docker images when [working with multiple registries with the same domain]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#working-with-multiple-registries-with-the-same-domain) | Optional | | `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | -| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) article. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/). | Optional | +| `retry` | Define retry behavior as described in [Retrying a step]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/#retrying-a-step). | Optional | ## Examples @@ -155,7 +155,7 @@ steps: {% endraw %} {% endhighlight %} -Push an image with multiple tags to multiple Docker registries in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/). +Push an image with multiple tags to multiple Docker registries in [parallel]({{site.baseurl}}/docs/pipelines/advanced-workflows/). Both registries are connected first in the [integrations page]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). @@ -230,28 +230,28 @@ step_name: {% endhighlight %} {: .table .table-bordered .table-hover} -| Field | Description | Required/Optional/Default | -| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| `title` | The free-text display name of the step. | Optional | -| `description` | A basic, free-text description of the step. | Optional | -| `provider` | The type of Docker registry provider. Can currently be either `docker` for a standard Docker registry, or `ecr` for the [Amazon EC2 Container Registry (ECR)](https://aws.amazon.com/ecr/). | Optional
*Default value*: `docker` | -| `candidate` | The identifier of the image to push to the remote Docker registry. It can be an explicit identifier of an image to push, or a variable that references a `Build` step. | Required | -| `tag` | The tag under which to push the image. Use either this or `tags`.
The default is `latest`. | Default | -| `tags` | Multiple tags under which to push the image. Use either this or 'tag'.
This is an array, so should be of the following style:
{::nomarkdown}
tags:
- tag1
- tag2
- {% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}
- tag4
{:/}or
{::nomarkdown}
tags: [ 'tag1', 'tag2', '{% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}', 'tag4' ]
{:/} | Default | -| `image_name` | The tagged image name that will be used. The default value will be the same image name as of the candidate. | Default | -| `registry` | The host address where the registry is located. The default is the registry configured in your Codefresh account, or Dockerhub. | Default
**Ignored when provider is** `ecr` | -| `credentials` | Credentials to access the registry if it requires authentication. It can be a has object containing `username` and `password` fields. The default is the credentials configured in your Codefresh account. | Optional
**Ignored when provider is** `ecr` | -| `accessKeyId` | Your AWS access key. | Optional
**Ignored when provider is** `docker` | -| `secretAccessKey` | Your AWS secret access key. | Optional
**Ignored when provider is** `docker` | -| `region` | The region where the ECR registry is accessible. | Optional
**Ignored when provider is** `docker` | -| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. | Default | -| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in the [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) article. | Optional | -| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). | Optional | +| Field | Description | Required/Optional/Default | +| ---------------------------- | ------------------------------------ | ----------------------------------------------- | +| `title` | The free-text display name of the step. | Optional | +| `description` | A basic, free-text description of the step. | Optional | +| `provider` | The type of Docker registry provider. Can currently be either `docker` for a standard Docker registry, or `ecr` for the [Amazon EC2 Container Registry (ECR)](https://aws.amazon.com/ecr/). | Optional
*Default value*: `docker` | +| `candidate` | The identifier of the image to push to the remote Docker registry. It can be an explicit identifier of an image to push, or a variable that references a `Build` step. | Required | +| `tag` | The tag under which to push the image. Use either this or `tags`.
The default is `latest`. | Default | +| `tags` | Multiple tags under which to push the image. Use either this or 'tag'.
This is an array, so should be of the following style:
{::nomarkdown}
tags:
- tag1
- tag2
- {% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}
- tag4
{:/}or
{::nomarkdown}
tags: [ 'tag1', 'tag2', '{% raw %}${{CF_BRANCH_TAG_NORMALIZED}}{% endraw %}', 'tag4' ]
{:/} | Default | +| `image_name` | The tagged image name that will be used. The default value will be the same image name as of the candidate. | Default | +| `registry` | The host address where the registry is located. The default is the registry configured in your Codefresh account, or Dockerhub. | Default
**Ignored when provider is** `ecr` | +| `credentials` | Credentials to access the registry if it requires authentication. It can be a has object containing `username` and `password` fields. The default is the credentials configured in your Codefresh account. | Optional
**Ignored when provider is** `ecr` | +| `accessKeyId` | Your AWS access key. | Optional
**Ignored when provider is** `docker` | +| `secretAccessKey` | Your AWS secret access key. | Optional
**Ignored when provider is** `docker` | +| `region` | The region where the ECR registry is accessible. | Optional
**Ignored when provider is** `docker` | +| `fail_fast` | If a step fails, and the process is halted. The default value is `true`. |Default | +| `when` | Define a set of conditions which need to be satisfied in order to execute this step.
You can find more information in [Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps. | Optional | +| `on_success`, `on_fail` and `on_finish` | Define operations to perform upon step completion using a set of predefined [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/).| Optional | **Exported resources:** - Image ID. -## What to read next -- [External Registry integrations]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) -- [Custom Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) -- [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) \ No newline at end of file +## Related articles +[External Registry integrations]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +[Custom Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) \ No newline at end of file diff --git a/_docs/pipelines/triggers.md b/_docs/pipelines/triggers.md index ca732a38..a074d9c5 100644 --- a/_docs/pipelines/triggers.md +++ b/_docs/pipelines/triggers.md @@ -1,7 +1,7 @@ --- -title: "Pipeline Triggers" +title: "Triggers for pipelines" description: "Choose when your pipelines should run" -group: configure-ci-cd-pipeline +group: pipelines redirect_from: - /docs/pipeline-triggers/ - /docs/pipeline-triggers/introduction-triggers/ @@ -14,20 +14,20 @@ To create an effective CI/CD process, it should be possible to trigger a Codefre Codefresh not only allows you to define different pipelines on a single project but it also offers you the capability to trigger them with completely separate mechanisms. -## Codefresh Trigger Types +## Pipeline trigger types -Trigger types currently supported by Codefresh are: +The following types of triggers are currently supported pipelines: -* [Git Triggers](git-triggers) -* [Dockerhub Triggers](dockerhub-triggers) -* [Azure Registry Triggers](azure-triggers) -* [Quay Triggers](quay-triggers) -* [Helm Triggers](helm-triggers) -* [Artifactory Triggers](jfrog-triggers) -* [Cron Trigger](cron-triggers) -* [API/CLI Trigger]({{site.baseurl}}/docs/integrations/codefresh-api/) +* [Git triggers](git-triggers) +* [Dockerhub triggers](dockerhub-triggers) +* [Azure Registry triggers](azure-triggers) +* [Quay triggers](quay-triggers) +* [Helm triggers](helm-triggers) +* [Artifactory triggers](jfrog-triggers) +* [Cron trigger](cron-triggers) +* [API/CLI trigger]({{site.baseurl}}/docs/integrations/codefresh-api/) -As an example, this project contains 4 pipelines: +As an example, this project contains four pipelines: {% include image.html lightbox="true" @@ -40,7 +40,7 @@ max-width="70%" Behind the scenes these pipelines are triggered from different events: -* Pipeline "CI-build" is using a GIT trigger and starts after every commit to the code repository +* Pipeline "CI-build" uses a GIT trigger and starts after every commit to the code repository * Pipeline "Sonarcloud" is executed every weekend using a cron (timed) trigger * Pipeline "integration-test" is executed whenever a commit happens in a Pull request on the code * Pipeline "deploy-prod-k8s" is executed whenever a Docker image is pushed to the Docker registry @@ -56,7 +56,7 @@ For all trigger types you can also use the [Codefresh CLI](https://codefresh-io. ## Creating a new trigger for a pipeline -By default, when you create a new project from a GIT provider it will start with a GIT trigger that runs on every commit. +By default, when you create a new project from a Git provider, it will start with a Git trigger that runs on every commit. {% include image.html lightbox="true" @@ -82,18 +82,18 @@ max-width="70%" For more information see: -* [Git Triggers](git-triggers) -* [Dockerhub Triggers](dockerhub-triggers) -* [Azure Registry Triggers](azure-triggers) -* [Quay Triggers](quay-triggers) -* [Helm Triggers](helm-triggers) -* [Artifactory Triggers](jfrog-triggers) -* [Cron Trigger](cron-triggers) +* [Git triggers](git-triggers) +* [Dockerhub triggers](dockerhub-triggers) +* [Azure Registry triggers](azure-triggers) +* [Quay triggers](quay-triggers) +* [Helm triggers](helm-triggers) +* [Artifactory triggers](jfrog-triggers) +* [Cron trigger](cron-triggers) ## Disabling triggers -You can easily disable a trigger manually if you don't want to be active anymore. -On the triggers tab click the gear icon on the top right (*Open advanced options*). +You can easily disable a trigger manually if you don't want it to be active anymore. +On the triggers tab, click the gear icon on the top right (*Open advanced options*). {% include image.html lightbox="true" @@ -108,9 +108,7 @@ max-width="70%" Then click the toggle switch on each trigger that you want to enable/disable. You can later enable the same trigger again by clicking the same switch. -## What to read next - -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [Git triggers](git-triggers) -* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) -* [Trigger a Kubernetes Deployment from a Dockerhub Push Event]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) +## Related articles +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Running pipelines locally]({{site.baseurl}}/docs/pipelines/running-pipelines-locally/) +[Trigger a Kubernetes Deployment from a Dockerhub Push Event]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) diff --git a/_docs/pipelines/triggers/azure-triggers.md b/_docs/pipelines/triggers/azure-triggers.md index f80f971c..5356be27 100644 --- a/_docs/pipelines/triggers/azure-triggers.md +++ b/_docs/pipelines/triggers/azure-triggers.md @@ -1,29 +1,29 @@ --- -title: "Azure Registry Trigger" -description: "Learn how to trigger Codefresh pipelines from Azure Registry events" -group: configure-ci-cd-pipeline +title: "Azure Registry trigger" +description: "Trigger Codefresh pipelines from Azure Registry events" +group: pipelines sub_group: triggers redirect_from: - /docs/pipeline-triggers/configure-azure-trigger/ toc: true --- -It is possible to define and manage Azure Registry Pipeline triggers with the Codefresh UI. +Define and manage Azure Registry triggers for pipelines with the Codefresh UI. This allows you to trigger Codefresh pipelines when an Azure Registry event happens (e.g. a new Docker image is uploaded). -## Manage Azure Triggers with Codefresh UI +## Manage Azure triggers with Codefresh UI The process involves two parts: -1. Creating a trigger in Codefresh. This will result in a special Codefresh webhook URL -1. Creating a new notification in the Azure Registry that will use this URL to call Codefresh +1. Creating a trigger in Codefresh. This will result in a special Codefresh webhook URL. +1. Creating a new notification in the Azure Registry that will use this URL to call Codefresh. -Make sure that you have an Azure cloud account and have already [created a registry](https://docs.microsoft.com/en-us/azure/container-registry/). +> Make sure that you have an Azure cloud account and have already [created a registry](https://docs.microsoft.com/en-us/azure/container-registry/). -### Create a new Azure Trigger +### Create a new Azure trigger To add a new Azure trigger, navigate to a Codefresh Pipeline *Configuration* view and expand the *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. @@ -51,7 +51,7 @@ alt="Azure Registry settings" max-width="50%" %} -Click next and a new Dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. +Click next and a new dialog will appear that shows you the Codefresh webhook URL. Copy it to your clipboard. {% include image.html @@ -64,11 +64,11 @@ max-width="50%" Now we must set Azure to call this URL when an event takes place. -### Setup Azure Notification +### Set up Azure notification The easiest way to create an Azure trigger is with the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/acr/webhook?view=azure-cli-latest#az-acr-webhook-create) (Also available in the Azure portal) -Here is the command +Here is the command: {% highlight shell %} {% raw %} @@ -83,3 +83,6 @@ The name can be anything you want. The URI is the Codefresh URL that was created Now, every time you push a new Docker image to the selected Azure Docker repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Azure Push trigger event. +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) \ No newline at end of file diff --git a/_docs/pipelines/triggers/cron-triggers.md b/_docs/pipelines/triggers/cron-triggers.md index ad9cc13b..93838253 100644 --- a/_docs/pipelines/triggers/cron-triggers.md +++ b/_docs/pipelines/triggers/cron-triggers.md @@ -1,7 +1,7 @@ --- title: "Cron Trigger" description: "Run pipelines with a time schedule" -group: configure-ci-cd-pipeline +group: pipelines sub_group: triggers redirect_from: - /docs/configure-cron-trigger/ @@ -11,7 +11,7 @@ toc: true Cron triggers allow you to create pipelines that start on a specific time schedule. This is very useful for cleanup jobs or periodic checks or any other workflow that needs to run after a time interval. ->All times mentioned in Cron triggers are using the UTC time zone. +>All times mentioned in Cron triggers use the UTC time zone. ## Manage Cron Triggers with Codefresh UI @@ -47,7 +47,7 @@ max-width="70%" %} -### Triggering Codefresh pipeline with cron timer +### Trigger Codefresh pipeline with cron timer Now, `cron` will trigger a recurrent pipeline execution based on the defined `cron expression`. @@ -55,7 +55,7 @@ Now, `cron` will trigger a recurrent pipeline execution based on the defined `cr It is also possible to use the Codefresh Command Line client (`CLI`) to manage Cron based pipeline triggers. -### Cron Trigger +### Cron trigger It is possible to trigger a Codefresh CD pipeline(s) periodically, using `cron` expression. @@ -77,7 +77,7 @@ When creating a `cron trigger-event`, it is possible to specify a short text mes Visit [this page](https://github.com/codefresh-io/cronus/blob/master/docs/expression.md) to learn about the supported `cron` expression format and aliases. -#### Setup pipeline trigger +#### Set up pipeline trigger Now, lets create a new pipeline trigger, linking previously defined `cron` `trigger-event` to one or more Codefresh pipelines. @@ -98,7 +98,7 @@ The following variables will be available for any Codefresh pipeline linked to a - `EVENT_MESSAGE` - free text message (specified during creation) - `EVENT_TIMESTAMP` - event timestamp in RFC 3339 format -## What to read next -- [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) -- [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) diff --git a/_docs/pipelines/triggers/dockerhub-triggers.md b/_docs/pipelines/triggers/dockerhub-triggers.md index 71dda94a..7d0e8079 100644 --- a/_docs/pipelines/triggers/dockerhub-triggers.md +++ b/_docs/pipelines/triggers/dockerhub-triggers.md @@ -1,7 +1,7 @@ --- -title: "DockerHub Trigger" +title: "DockerHub triggers" description: "" -group: configure-ci-cd-pipeline +group: pipelines sub_group: triggers redirect_from: - /docs/configure-dockerhub-trigger/ @@ -9,11 +9,10 @@ redirect_from: toc: true --- -## Manage DockerHub Triggers with Codefresh UI -It is possible to define and manage DockerHub pipeline triggers with Codefresh UI. +You can define and manage DockerHub triggers in Codefresh. -### Create a new DockerHub Trigger +### Create a new DockerHub trigger in Codefresh UI To add a new DockerHub trigger, navigate to Codefresh Pipeline *Configuration* view and expand *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. @@ -43,7 +42,7 @@ max-width="70%" ### Setup DockerHub Webhook -Currently Codefresh does not support to automatically setup a DockerHub webhook. You need to do this manually. Press the *Next* button and see detailed instructions with URL links and secrets of how-to setup a DockerHub Webhook. +Currently Codefresh does not support automatically setting up a DockerHub webhook. You need to do this manually. Press the *Next* button and see detailed instructions with URL links and secrets of how-to setup a DockerHub Webhook. {% include image.html @@ -62,13 +61,13 @@ max-width="70%" Now, every time you push a new Docker image to selected DockerHub repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with this DockerHub Push trigger event. -## Manage DockerHub Triggers with Codefresh CLI +## Manage DockerHub triggers with Codefresh CLI It is possible to use `codefresh` command line client (`CLI`) to manage DockerHub pipeline triggers. ### Docker Hub Trigger -It is possible to trigger a Codefresh CD pipeline(s) when a new Docker image pushed into DockerHub. +It is possible to trigger Codefresh CD pipeline(s) when a new Docker image pushed into DockerHub. You can use [Codefresh CLI](https://cli.codefresh.io/) to setup a Codefresh trigger for DockerHub. @@ -84,9 +83,9 @@ codefresh create trigger-event --type registry --kind dockerhub --value namespac Trigger event: registry:dockerhub:codefresh:fortune:push:107e9db97062 was successfully created. ``` -#### Setup DockerHub Webhook +#### Set up DockerHub webhook -Currently, an additional manual work is required to bind DockerHub `push` image event to the Codefresh `trigger-event`. +Currently, an additional manual action is required to bind DockerHub `push` image event to the Codefresh `trigger-event`. ```sh # get trigger-event details for previously created trigger-event @@ -119,13 +118,13 @@ help: >- ``` 1. Copy `endpoint` URL -1. Visit DockerHub settings page [https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/](https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/) -1. Add a new Webhook with previously copied `endpoint` URL +1. Visit DockerHub settings page [https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/](https://hub.docker.com/r/codefresh/fortune/~/settings/webhooks/). +1. Add a new Webhook with previously copied `endpoint` URL. -#### Setup pipeline trigger +#### Set up pipeline trigger -Now, lets setup a new pipeline trigger, linking previously defined DockerHub push `codefresh/fortune` `trigger-event` to one ore more Codefresh pipelines. +Now, lets set up a new pipeline trigger, linking previously defined DockerHub push `codefresh/fortune` `trigger-event` to one or more Codefresh pipelines. ```sh # create trigger, linking trigger-event UID to the pipeline UID @@ -147,3 +146,7 @@ The following variables will be available for any Codefresh pipeline linked to a - `EVENT_PUSHER` - user who pushed this Docker image. - `EVENT_PUSHED_AT` - timestamp for push event. - `EVENT_PAYLOAD` - original DockerHub Webhook JSON payload. + +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) diff --git a/_docs/pipelines/triggers/git-triggers.md b/_docs/pipelines/triggers/git-triggers.md index 81981056..ce1d37ce 100644 --- a/_docs/pipelines/triggers/git-triggers.md +++ b/_docs/pipelines/triggers/git-triggers.md @@ -1,25 +1,25 @@ --- -title: "Git Triggers" +title: "Git triggers" description: "Learn how to run pipelines from Git events" -group: configure-ci-cd-pipeline +group: pipelines sub_group: triggers toc: true --- -GIT triggers are the most basic types of trigger for performing [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) with Codefresh. +Git triggers are the most basic of the trigger typesfor performing [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) with Codefresh. -At the trigger level you have the option of selecting: +At the trigger level, you can select: * Which code repository will be used as a trigger * Which branches will be affected by a pipeline -* If a trigger will apply to a Pull Request or not +* If a trigger will apply to a Pull Request (PR) or not - Note that you can select another repository other than the one the project itself belongs to. It is possible +> You can select a repository other than the one the project itself belongs to. It is possible to trigger a build on project A even though a commit happened on project B. -You can also use [Conditional expressions]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) at the pipeline level to further fine-tune the way specific steps (or other transitive pipelines) are executed. +You can also use [conditional expressions]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) at the pipeline level to further fine-tune the way specific steps (or other transitive pipelines) are executed. -## Manage GIT Triggers with Codefresh UI +## Manage GIT triggers with Codefresh UI To add a new GIT trigger, navigate to the Codefresh Pipeline *Configuration* view and expand the *Triggers* section on the right side. Press the *Add Trigger* button and select a *GIT* trigger type to add. @@ -31,7 +31,7 @@ alt="Adding new Trigger dialog" max-width="60%" %} -## General Trigger Settings +## General trigger Settings {% include image.html lightbox="true" @@ -41,7 +41,7 @@ alt="Adding GIT Trigger" max-width="50%" %} -The Git Trigger is comprised of the following settings: +The Git trigger is comprised of the following settings: * *Trigger Name* - a freetext trigger name (required). * *Description* - a freetext description (optional). @@ -111,7 +111,7 @@ Therefore, all tags like `tag1`, `tag-X` **won't** trigger the pipeline. ### Pull Requests from comments -Pull Requests from comments are supported for all Git providers, for private and public repositories. +Pull Requests from comments are supported for all Git providers, for both private and public repositories. There are two options: * **Pull request comment added (restricted)** This option triggers an event only when the PR comments are made by repository owners or collaborators. @@ -158,7 +158,7 @@ Once that is done, Codefresh will launch your pipeline against the Pull Request. When supporting building of pull requests from forks there are a few "gotchas" to look out for: * Only comments made by repository owners and [collaborators](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/adding-outside-collaborators-to-repositories-in-your-organization) will result in the pipeline being triggered. -* Only git pushes by collaborators within the GitHub organization will result in the pipeline being triggered +* Only Git pushes by collaborators within the GitHub organization will result in the pipeline being triggered * If the repository is in a GitHub organization, comments made by private members of the organization will not activate the trigger, even if they are set as an owner or collaborator. Private members means that they need to be explicitly added to the repository. Access cannot be "inherited" by the GitHub team. Currently, only comments from Admins, or Collaborators (directly added, not via teams) are allowed, in order to be caught by this filter. * The *Pull request comment added* checkbox should likely be the only one checked, or your pipeline may trigger on other events that you don't anticipate. @@ -257,9 +257,9 @@ max-width="60%" * *Report notification on pipeline execution* - Decide if [Slack notifications]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) will be sent (as well as status updates back to your Git provider) * *Runtime Environment* - choose to use pipeline [settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) or override them -## Manually Adding the Trigger to GitHub +## Manually adding the trigger to GitHub -When creating a Git Trigger in codefresh, sometimes the Git Integration does not have the permissions to create a webhook on the designated repository. When this happens, you get the following error: `Failed to add Trigger`. +When creating a Git trigger in codefresh, sometimes the Git Integration does not have the permissions to create a webhook on the designated repository. When this happens, you get the following error: `Failed to add Trigger`. This error means that Codefresh could not create the webhook and verify that it works. With that, Codefresh will mark the Trigger as Unverified. Two additional fields (Endpoint and Secret) will appear under the "Verify Trigger" button when you get this error. @@ -268,12 +268,11 @@ This error means that Codefresh could not create the webhook and verify that it ### Adding Webhook to Github -1. When you receive the `Failed to add Trigger`. -2. Log into GitHub - - Make this user can access the repository settings and create Webhooks -3. Go to the repository mentioned in the "REPOSITORY" section from Unverified Trigger. -4. Go to Settings > Webhooks and click the "Add webhook" button. -5. Fill in the form +1. When you receive the `Failed to add Trigger`, log into GitHub. + - Make sure this user can access the repository settings and create Webhooks +1. Go to the repository mentioned in the "REPOSITORY" section from Unverified Trigger. +1. Go to Settings > Webhooks and click the "Add webhook" button. +1. Fill in the form - **Payload URL**: The URL from the Endpoint field from the Trigger - **Content type**: application/json - **Secret**: The token in the Secret field from the Trigger @@ -282,16 +281,15 @@ This error means that Codefresh could not create the webhook and verify that it 1. Select let me select individual events 2. Match the items selected in the Trigger By field from the Trigger - **Active**: Make sure this is selected -6. Click "Add webhook" when done. -7. Click "Done" in the Add Trigger form. -8. Test your webhook by making an event in the repository that will cause the Trigger to start the build. +1. Click "Add webhook" when done. +1. Click "Done" in the Add Trigger form. +1. Test your webhook by making an event in the repository that will cause the Trigger to start the build. > **Note**: -> -> - You will be responsible for syncing the Trigger By to the Events sent to us for the webhook. You can select "Send me everything" if you do not want to manually match the Trigger By in the Trigger with the Webhook Events in GitHub. -> - The Trigger will remain "Unverified" until the integration has the correct permissions to the repository. + * You will be responsible for syncing the Trigger By to the Events sent to us for the webhook. You can select "Send me everything" if you do not want to manually match the Trigger By in the Trigger with the Webhook Events in GitHub. + * The Trigger will remain "Unverified" until the integration has the correct permissions to the repository. -## Accessing directly the webhook content of the trigger +## Accessing webhook content of the trigger directly If your Git trigger is coming from Github, you can also access the whole payload of the webhook that was responsible for the trigger. The webhook content is available at `/codefresh/volume/event.json`. You can read this file in any pipeline step and process it like any other json file (e.g. with the jq utility). @@ -358,8 +356,8 @@ It has only a single step which uses conditionals that check the name of the bra The build step calls the second pipeline. The end result is that pipeline B runs only when the Pull Request is opened the first time. Any further commits on the pull request branch will **not** trigger pipeline B (pipeline A will still run but the conditionals will fail). -## What to read next - -* [Cron triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/cron-triggers/) -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [Multi-git trigger]({{site.baseurl}}/docs/troubleshooting/common-issues/multi-git-triggers/) +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Cron triggers]({{site.baseurl}}/docs/pipelines/triggers/cron-triggers/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Multi-git trigger]({{site.baseurl}}/docs/troubleshooting/common-issues/multi-git-triggers/) diff --git a/_docs/pipelines/triggers/helm-triggers.md b/_docs/pipelines/triggers/helm-triggers.md index a2956373..98ede0e9 100644 --- a/_docs/pipelines/triggers/helm-triggers.md +++ b/_docs/pipelines/triggers/helm-triggers.md @@ -6,13 +6,11 @@ sub_group: triggers toc: true --- -Codefresh has the option to create pipelines that respond to Helm events. For instance, one pipeline can be set-up to create a Docker image and chart. Once those are created, another pipeline will be triggered that will take over the actual deployment. +Codefresh has the option to create pipelines that respond to Helm events. For instance, one pipeline can be set-up to create a Docker image and chart. Once those are created, another pipeline is triggered to implement the actual deployment. -## Manage Helm Triggers with Codefresh UI +Define and manage Helm pipeline triggers with the Codefresh UI. -It is possible to define and manage Helm pipeline triggers with the Codefresh UI. - -### Create a new Helm Trigger +## Create a new Helm Trigger To add a new Helm trigger, navigate to Codefresh Pipeline *Configuration* view and expand *Triggers* section. Press the `Add Trigger` button and select the `Helm` trigger type to add. @@ -49,14 +47,15 @@ alt="Codefresh webhook URL" max-width="50%" %} -Now we must set JFrog Artifactory to call this URL when an event takes place. This can either be done through the [JFrog Artifactory webhook plugin](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/jfrog-triggers/) or through [setting up Webhooks](https://www.jfrog.com/confluence/display/JFROG/Webhooks) in the UI. +Now we must set JFrog Artifactory to call this URL when an event takes place. This can either be done through the [JFrog Artifactory webhook plugin]({{site.baseurl}}/docs/pipelines/triggers/jfrog-triggers/) or through [setting up Webhooks](https://www.jfrog.com/confluence/display/JFROG/Webhooks) in the UI. -### Triggering a Codefresh pipeline with an Artifactory push +## Trigger Codefresh pipeline with an Artifactory push Now, every time you push a Helm chart to the selected Artifactory repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Artifactory Push trigger event. -## What to read next -* [Git triggers](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/git-triggers/) -* [Helm Releases management](https://codefresh.io/docs/docs/new-helm/helm-releases-management/) -* [Custom Helm uploads](https://codefresh.io/docs/docs/new-helm/custom-helm-uploads/) \ No newline at end of file +## Related articles +[Helm Releases management](https://codefresh.io/docs/docs/new-helm/helm-releases-management/) +[Custom Helm uploads](https://codefresh.io/docs/docs/new-helm/custom-helm-uploads/) +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) diff --git a/_docs/pipelines/triggers/jfrog-triggers.md b/_docs/pipelines/triggers/jfrog-triggers.md index 4a86b503..97471f4d 100644 --- a/_docs/pipelines/triggers/jfrog-triggers.md +++ b/_docs/pipelines/triggers/jfrog-triggers.md @@ -1,6 +1,6 @@ --- -title: "Artifactory Trigger" -description: "How to trigger Codefresh pipelines from Artifactory" +title: "Artifactory trigger" +description: "Trigger Codefresh pipelines from Artifactory" group: configure-ci-cd-pipeline sub_group: triggers redirect_from: @@ -8,8 +8,8 @@ redirect_from: toc: true --- -It is possible to define and manage Artifactory pipeline triggers with the Codefresh UI. -This allows you to trigger Codefresh pipelines when a Artifactory event happens (i.e. a new Docker image is uploaded). +Define and manage Artifactory pipeline triggers with the Codefresh UI. +This allows you to trigger Codefresh pipelines when an Artifactory event occurs (i.e. a new Docker image is uploaded). ## Manage Artifactory Triggers with Codefresh UI @@ -19,9 +19,9 @@ The process involves two parts: 1. Creating a trigger in Codefresh. This will result in a special Codefresh webhook URL 1. Activating the [webhook plugin](https://github.com/jfrog/artifactory-user-plugins/tree/master/webhook) in Artifactory and setting it up to call the Codefresh URL -Make sure that you have admin access to your Artifactory instance in order to setup its webhook plugin. +> Make sure that you have admin access to your Artifactory instance in order to setup its webhook plugin. -### Create a new Artifactory Trigger +### Create a new Artifactory trigger To add a new Artifactory trigger, navigate to a Codefresh Pipeline *Configuration* view and expand the *Triggers* section. Press the `Add Trigger` button and select a `Registry` trigger type to add. @@ -62,7 +62,7 @@ max-width="50%" Now we must set JFrog Artifactory to call this URL when an event takes place. -### Setup JFrog Artifactory webhook plugin +### Set up JFrog Artifactory webhook plugin The [webhook functionality](https://github.com/jfrog/artifactory-user-plugins/tree/master/webhook) in JFrog artifactory comes in plugin. You can read [detailed documentation](https://www.jfrog.com/confluence/display/RTF/User+Plugins) for JFrog plugins but in summary: @@ -92,7 +92,10 @@ Here is an example for Codefresh. -### Triggering a Codefresh pipeline with an Artifactory push +### Trigger a Codefresh pipeline with an Artifactory push Now, every time you push/tag a Docker image to the selected Artifactory repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Artifactory Push trigger event. +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) \ No newline at end of file diff --git a/_docs/pipelines/triggers/quay-triggers.md b/_docs/pipelines/triggers/quay-triggers.md index 682dec12..1e7e275f 100644 --- a/_docs/pipelines/triggers/quay-triggers.md +++ b/_docs/pipelines/triggers/quay-triggers.md @@ -1,17 +1,17 @@ --- title: "Quay Trigger" -description: "How to trigger Codefresh pipelines from Quay" -group: configure-ci-cd-pipeline +description: "Trigger Codefresh pipelines from Quay" +group: pipelines sub_group: triggers redirect_from: - /docs/pipeline-triggers/configure-quay-trigger/ toc: true --- -It is possible to define and manage Quay pipeline triggers with the Codefresh UI. +Define and manage Quay triggers for pipelines with the Codefresh UI. This allows you to trigger Codefresh pipelines when a Quay event happens (e.g. a new Docker image is uploaded). -## Manage Quay Triggers with Codefresh UI +## Manage Quay triggers with Codefresh UI The process involves two parts: @@ -19,7 +19,7 @@ The process involves two parts: 1. Creating a trigger in Codefresh (this will result in a special Codefresh webhook URL) 1. Creating a new notification in Quay that will use this URL to call Codefresh -Make sure that you have a Quay account and have already [created a repository](https://docs.quay.io/guides/create-repo.html) (or pushed a Docker image at least once). +> Make sure that you have a Quay account and have already [created a repository](https://docs.quay.io/guides/create-repo.html) (or pushed a Docker image at least once). ### Create a new Quay Trigger @@ -63,7 +63,7 @@ max-width="50%" Now we must set Quay to call this URL when an event takes place. -### Setup Quay Notification +### Set up Quay notification Log in your Quay account and go to the respective repository. You can also click the link shown in the Codefresh dialog to go directly to the settings of that repository. @@ -97,3 +97,6 @@ Finally click *Create Notification*. Now, every time you push a new Docker image to the selected Quay repository, manually, with Codefresh or any other CI/CD tool, Codefresh will trigger execution of all pipelines associated with that Quay Push trigger event. +## Related articles +[Triggers for pipelines]({{site.baseurl}}/docs/pipelines/triggers) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) \ No newline at end of file From d43592c109b685b4569f705c65e2b4aa8a3c5d6c Mon Sep 17 00:00:00 2001 From: NimRegev Date: Thu, 1 Dec 2022 18:22:45 +0200 Subject: [PATCH 3/8] Update after porting --- _docs/pipelines/annotations.md | 23 +++++----- _docs/pipelines/docker-image-metadata.md | 22 +++++----- _docs/pipelines/hooks.md | 38 ++++++++--------- _docs/pipelines/stages.md | 26 ++++++------ _docs/pipelines/variables.md | 54 ++++++++++++------------ 5 files changed, 81 insertions(+), 82 deletions(-) diff --git a/_docs/pipelines/annotations.md b/_docs/pipelines/annotations.md index 58886a6e..d82fc37d 100644 --- a/_docs/pipelines/annotations.md +++ b/_docs/pipelines/annotations.md @@ -1,5 +1,5 @@ --- -title: "Annotations" +title: "Annotations in pipelines" description: "Mark your builds and projects with extra annotations" group: codefresh-yaml toc: true @@ -17,12 +17,12 @@ Currently Codefresh supports extra annotations for: You can view/edit annotations using the [Codefresh CLI](https://codefresh-io.github.io/cli/annotations/) or directly in the Codefresh Web UI. >Notice that the syntax shown in this page is deprecated but still supported. For the new syntax -see our [hooks documentation]({{site.baseurl}}/docs/codefresh-yaml/hooks/). +see [hooks]({{site.baseurl}}/docs/pipelines/hooks/). ## Adding annotations -In the most basic scenario you can use the [post operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) of any Codefresh [step]({{site.baseurl}}/docs/codefresh-yaml/steps/) to add annotations: +In the most basic scenario you can use the [post operations]({{site.baseurl}}/docs/pipelines/post-step-operations/) of any Codefresh [step]({{site.baseurl}}/docs/pipelines/steps/) to add annotations: `codefresh.yml` {% highlight yaml %} @@ -92,7 +92,7 @@ steps: It is therefore possible to store annotations on any Codefresh entity (and not just the ones that are connected to the build that is adding annotations). -## Viewing/Editing annotations +## Viewing/editing annotations You can view the annotations using the Codefresh CLI @@ -162,7 +162,7 @@ Click *Save* to apply your changes. ## Complex annotation values -Apart from scalar values, you can also store more complex expressions in annotations. You have access to all [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/), text files from the build and even evaluations from the [expression syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +Apart from scalar values, you can also store more complex expressions in annotations. You have access to all [Codefresh variables]({{site.baseurl}}/docs/pipelines/variables/), text files from the build and even evaluations from the [expression syntax]({{site.baseurl}}/docs/pipelines/condition-expression-syntax/). `codefresh.yml` {% highlight yaml %} @@ -195,7 +195,7 @@ steps: {% endraw %} {% endhighlight %} ->Notice that this pipeline is using dynamic git repository variables, so it must be linked to a least one [git trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) in order to work. +>Notice that this pipeline is using dynamic git repository variables, so it must be linked to a least one [git trigger]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) in order to work. The last two annotations add the text of a file as a value. You can define an absolute or relative path. No processing is done on the file before being stored. If a file is not found, the annotation will still be added verbatim. We suggest you only store small text files in this manner as annotations values. @@ -295,9 +295,8 @@ You can also define `entity_type` as `image` and don't enter any `entity_id`. In Note that this syntax is optional. You can still define annotations for a build/image or any other entity using the post operations of any step by mentioning explicitly the target id and type. -## What to read next - -* [Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) -* [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/) -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) +## Related articles +[Image annotations]({{site.baseurl}}/docs/docker-registries/metadata-annotations/) +[Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Hooks in pipelines]({{site.baseurl}}/docs/pipelines/hooks/) diff --git a/_docs/pipelines/docker-image-metadata.md b/_docs/pipelines/docker-image-metadata.md index ca4f9ca6..02cad04a 100644 --- a/_docs/pipelines/docker-image-metadata.md +++ b/_docs/pipelines/docker-image-metadata.md @@ -1,7 +1,7 @@ --- -title: "Docker image Metadata" +title: "Docker image metadata" description: "How to use custom metadata in your Docker images" -group: codefresh-yaml +group: pipelines redirect_from: - /docs/metadata-annotations/ - /docs/docker-registries/metadata-annotations/ @@ -19,8 +19,8 @@ This article explains how to create advanced view of your images and enrich them max-width="65%" %} ->We have since expanded this feature and now you are able to add custom annotations to [pipelines and builds as well]({{site.baseurl}}/docs/codefresh-yaml/annotations/). Notice also that the syntax shown in this page is deprecated but still supported. For the new syntax -see our [hooks documentation]({{site.baseurl}}/docs/codefresh-yaml/hooks/). +>We have since expanded this feature and now you are able to add custom annotations to [pipelines and builds as well]({{site.baseurl}}/docs/pipelines/annotations/). Notice also that the syntax shown in this page is deprecated but still supported. For the new syntax +see [Hooks in pipelines]({{site.baseurl}}/docs/pipelines/hooks/). ## Metadata types @@ -39,11 +39,11 @@ Metadata values may be of the following types: You can also use [Expression evaluations]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/#condition-expression-syntax) to set metadata. ## Annotate your images using Codefresh YAML -You can annotate an image as part of it's builds process and also on post build steps. +You can annotate an image as part of its build process and also on post build steps. {:.text-secondary} ### Build step Image Metadata Annotation -You can annotate an image as part of its build process by declaring the metadata value on the [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/): +You can annotate an image as part of its build process by declaring the metadata value on the [Build step]({{site.baseurl}}/docs/pipelines/steps/build/): 1. The `metadata` attribute 2. The `set` operation 3. An array of key-value metadata @@ -64,7 +64,7 @@ build_step: {:.text-secondary} ### Adding annotations to Built images on post-build steps -Any step in the YAML workflow can annotate built images by using [Post-Step Operations]({{site.baseurl}}/docs/codefresh-yaml/post-step-operations/). +Any step in the YAML workflow can annotate built images by using [Post-Step Operations]({{site.baseurl}}/docs/pipelines/post-step-operations/). To annotate a built image, configure any step with: 1. The post-step operation 2. The `metadata` attribute @@ -212,8 +212,6 @@ The possibilities are endless as you can take any combination of image metadata in order to process them in a Codefresh pipeline. -### See also - -* [External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) -* [Accessing a Docker registry from your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/access-docker-registry-from-kubernetes/) -* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) +## Related articles +[External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) +[Accessing a Docker registry from your Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/access-docker-registry-from-kubernetes/) diff --git a/_docs/pipelines/hooks.md b/_docs/pipelines/hooks.md index 8996932c..5505f688 100644 --- a/_docs/pipelines/hooks.md +++ b/_docs/pipelines/hooks.md @@ -1,13 +1,13 @@ --- -title: "Hooks" +title: "Hooks in pipelines" description: "Execute commands before/after each pipeline or step" -group: codefresh-yaml +group: pipelines toc: true --- -Pipeline hooks allow you to run specific actions at the end and the beginning of the pipeline as well as before/after a step. +Hooks in pipelines allow you to run specific actions at the end and the beginning of the pipeline, as well as before/after a step. -Hooks can be a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) as you need to define: +Hooks can be a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/), as you need to define: 1. A Docker image that will be used to run specific commands. 1. One or more commands to run within the context of that Docker image. @@ -109,7 +109,7 @@ Note that if you have multiple hooks like the example above, the `on_finish` seg ### Running a step at the start of the pipeline -Similar to the end of the pipeline, you can also execute a step in the beginning of the pipeline with the `on_elected` keyword: +Similar to the end of the pipeline, you can also execute a step at the beginning of the pipeline with the `on_elected` keyword: `codefresh.yml` {% highlight yaml %} @@ -249,7 +249,7 @@ steps: {% endraw %} {% endhighlight %} -The order of events in the example above is the following. +The order of events in the example above is the following: 1. The `on_elected` segment executes first (authentication) 1. The step itself executes (the security scan) @@ -257,9 +257,9 @@ The order of events in the example above is the following. 1. The `on_finish` segment always executes at the end -## Running [steps/plugins](https://steps.codefresh.io) in hooks: +## Running steps/plugins in hooks -Hooks can use [steps/plugins](https://steps.codefresh.io). With plugin you have to specify: +Hooks can use [steps/plugins](https://steps.codefresh.io). With plugins you have to specify: - The type field for the step/plugin. - The arguments needed for the step/plugin. @@ -298,7 +298,9 @@ steps: ## Controlling errors inside pipeline/step hooks -By default if a step fails within a pipeline, the whole pipeline will stop and be marked as failed. This is also true for `on_elected` segments as well. If they fail, then the whole pipeline will fail (regardless of the position of the segment in a pipeline or step). However, this only applies to `on_elected` segments - `on_success`, `on_fail` and `on_finish` segments do not affect the pipeline outcome at all, and a pipeline will continue even if one of these segments fails. +By default if a step fails within a pipeline, the whole pipeline will stop and be marked as failed. +This is also true for `on_elected` segments as well. If they fail, then the whole pipeline will fail (regardless of the position of the segment in a pipeline or step). However, this only applies to `on_elected` segments. +`on_success`, `on_fail` and `on_finish` segments do not affect the pipeline outcome at all, and a pipeline will continue even if one of these segments fails. For example the following pipeline will fail right away, because the pipeline hook fails at the beginning. @@ -404,7 +406,7 @@ steps: {% endraw %} {% endhighlight %} -By default all steps in a single hook segment are executed one after the other. But you can also run them in [parallel]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#inserting-parallel-steps-in-a-sequential-pipeline): +By default all steps in a single hook segment are executed one after the other. But you can also run them in [parallel]({{site.baseurl}}/docs/pipelines/advanced-workflows/#inserting-parallel-steps-in-a-sequential-pipeline): `codefresh.yml` {% highlight yaml %} @@ -444,7 +446,7 @@ You can use multiple steps in a hook in both the pipeline and the step level. ## Using annotations and labels in hooks -The hook syntax can also be used as a unified interface for encompassing the existing syntax of [build annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) and [metadata]({{site.baseurl}}/docs/codefresh-yaml/docker-image-metadata/). +The hook syntax can also be used as a unified interface for encompassing the existing syntax of [build annotations]({{site.baseurl}}/docs/pipelines/annotations/) and [metadata]({{site.baseurl}}/docs/pipelines/docker-image-metadata/). `codefresh.yml` {% highlight yaml %} @@ -619,16 +621,14 @@ hooks: With the current implementation of hooks, the following limitations are present: -* The [debugger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/debugging-pipelines/) cannot inspect commands inside hook segments -* Hooks are not supported for [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +* The [debugger]({{site.baseurl}}/docs/pipelines/debugging-pipelines/) cannot inspect commands inside hook segments +* Hooks are not supported for [parallel steps]({{site.baseurl}}/docs/pipelines/advanced-workflows/) * Storage integrations don't resolve in hooks (for example, [test reports]({{site.baseurl}}/docs/testing/test-reports/#producing-allure-test-reports-from-codefresh-pipelines)) * Step hook does not support the working_directory field aka `working_directory: ${{clone}}` -## What to read next - -* [Conditional Execution of Steps]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) -* [Condition Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) -* [Working Directories]({{site.baseurl}}/docs/codefresh-yaml/working-directories/) -* [Annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +## Related articles +[Conditional Execution of Steps]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) +[Working Directories]({{site.baseurl}}/docs/pipelines/working-directories/) +[Annotations]({{site.baseurl}}/docs/pipelines/annotations/) diff --git a/_docs/pipelines/stages.md b/_docs/pipelines/stages.md index aac05a2e..e6e0b103 100644 --- a/_docs/pipelines/stages.md +++ b/_docs/pipelines/stages.md @@ -1,11 +1,13 @@ --- -title: "Pipeline Stages" -description: "Grouping steps in stages for better visualization" -group: codefresh-yaml +title: "Grouping steps in pipelines" +description: "Group steps into stages for better visualization" +group: pipelines toc: true --- -With Codefresh you can [create really complex pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) with any number of steps. To better visualize the pipeline, you can group several steps into a single _stage_ that will show up as a separate column in the [pipeline view]({{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/). +With Codefresh you can [create really complex pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) with any number of steps. + +To better visualize the pipeline, you can group several steps into a single _stage_. The _stage_ with the group of steps are displayed as a separate column in the [pipeline view]({{site.baseurl}}/docs/pipelines/monitoring-pipelines/). {% include image.html @@ -17,11 +19,11 @@ caption="Complex pipeline" max-width="70%" %} -In this example there are 4 pipeline stages. +In this example, the pipeline has four stages. -## Assigning steps to a stage. +## Assigning steps to a stage -Stages are completely optional and for really small pipelines they are not needed at all. +Stages are completely optional, and for really small pipelines they are not needed at all. By default, all pipeline steps are shown one after the other. {% include @@ -75,7 +77,8 @@ As you can see the modifications needed are: 1. To list all the stage names at the root of the pipeline file 1. To use the `stage` property on each step to assign it to a stage ->This updated pipeline view is only a nice way to visualize the pipeline. It does not affect the order of step execution. Steps will still execute in the same order listed in the `codefresh.yml` file. If you wish to use parallel execution and advanced workflows see the [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) page. +>This updated pipeline view affects only the visualization of the pipeline. It does not affect the order of step execution. Steps are still executed in the same order as listed in the `codefresh.yml` file. + If you wish to use parallel execution and advanced workflows see the [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) page. ## Example pipeline with several stages @@ -187,7 +190,6 @@ steps: {% endhighlight %} -## What to read next - -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Parallel workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +## Related articles +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Parallel workflows]({{site.baseurl}}/docs/pipelines/advanced-workflows/) diff --git a/_docs/pipelines/variables.md b/_docs/pipelines/variables.md index 5da55e75..371b0443 100644 --- a/_docs/pipelines/variables.md +++ b/_docs/pipelines/variables.md @@ -77,16 +77,16 @@ feature-vb145dh Notice that this syntax is specific to Codefresh and is **only** available within the Codefresh YAML file itself. If you want to write scripts or programs that use the Codefresh variables, you need to make them aware of the environment variable form. . -## System Provided Variables +## System variables All system provided variables will also be automatically injected to any freestyle step as environment variables. > It is important to understand that all Git related variables such `CF_BRANCH`, `CF_COMMIT_MESSAGE`, `CF_REVISION` etc. are coming directly from the Git provider you use and have the same limitations of that provider. For example GitLab is sending less information in pull request events than normal pushes, and Bitbucket sends only the short hash of a commit in pull request events. We suggest you read the documentation of your Git provider first to understand what information is available for every Git event {: .table .table-bordered .table-hover} -| Variable | Description | -| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| {% raw %}`${{CF_REPO_OWNER}} `{% endraw %} | Repository owner. | +| Variable | Description | +| ------------------------------------------------- | ------------------------------------------------------ | +| {% raw %}`${{CF_REPO_OWNER}} `{% endraw %} | Repository owner. | | {% raw %}`${{CF_REPO_NAME}}`{% endraw %} | Repository name. | | {% raw %}`${{CF_BRANCH}}`{% endraw %} | Branch name (or Tag depending on the payload json) of the Git repository of the main pipeline, at the time of execution.
You can also use {% raw %}`${{CF_BRANCH_TAG_NORMALIZED}}`{% endraw %} to get the branch name normalized. It will be without any chars that are illegal in case the branch name were to be used as the Docker image tag name. You can also use {% raw %}`${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}`{% endraw %} to force lowercase. | | {% raw %}`${{CF_BASE_BRANCH}}`{% endraw %} | The base branch used during creation of Tag | @@ -96,31 +96,31 @@ All system provided variables will also be automatically injected to any freesty | {% raw %}`${{CF_PULL_REQUEST_ID}}`{% endraw %} | The pull request id | | {% raw %}`${{CF_PULL_REQUEST_LABELS}}`{% endraw %} | The labels of pull request (GitHub and GitLab only) | | {% raw %}`${{CF_COMMIT_AUTHOR}}`{% endraw %} | Commit author. | -| {% raw %}`${{CF_BUILD_INITIATOR}}`{% endraw %} | The person (username) that started the build. If the build was started by a Git webhook (e.g. from a Pull request) it will hold the webhook user. Notice that if a build is restarted manually it will always hold the username of the person that restarted it. | +| {% raw %}`${{CF_BUILD_INITIATOR}}`{% endraw %} | The person (username) that started the build. If the build was started by a Git webhook (e.g. from a Pull request) it will hold the webhook user. Notice that if a build is restarted manually it will always hold the username of the person that restarted it. | | {% raw %}`${{CF_ACCOUNT}}`{% endraw %} | Codefresh account for this build | -| {% raw %}`${{CF_COMMIT_URL}}`{% endraw %} | Commit url. | -| {% raw %}`${{CF_COMMIT_MESSAGE}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
The messages quotes are escaped (i.e. ' is not \', " is now \"). | -| {% raw %}`${{CF_COMMIT_MESSAGE_ESCAPED}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
Special characters are escaped. | +| {% raw %}`${{CF_COMMIT_URL}}`{% endraw %} | Commit url. | +| {% raw %}`${{CF_COMMIT_MESSAGE}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
The messages quotes are escaped (i.e. ' is not \', " is now \"). | +| {% raw %}`${{CF_COMMIT_MESSAGE_ESCAPED}}`{% endraw %} | Commit message of the Git repository revision, at the time of execution.
Special characters are escaped. | | {% raw %}`${{CF_REVISION}}`{% endraw %} | Revision of the Git repository of the main pipeline, at the time of execution.
You can also use {% raw %}`${{CF_SHORT_REVISION}}`{% endraw %} to get the abbreviated 7-character revision hash, as used in Git. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_SHORT_REVISION}}`{% endraw %} | -| {% raw %}`${{CF_VOLUME_NAME}}`{% endraw %} | Refers to the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) between [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). Normally you only need to define this in [compositions]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/). In freestyle steps, it is automatically present without any extra configuration. | -| {% raw %}`${{CF_VOLUME_PATH}}`{% endraw %} | Refers to the mounted path of the [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) inside a Freestyle container. In the current implementation it expands to `/codefresh/volume`. | -| {% raw %}`${{CF_BUILD_TRIGGER}}`{% endraw %} | Will be an indication of the current build was triggered: *build: The build was triggered from the build button* webhook: The build was triggered from a control version webhook | -| {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | The build id. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | -| {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | The timestamp the build was created. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | -| {% raw %}`${{CF_BUILD_URL}}`{% endraw %} | The URL to the build in Codefresh | -| {% raw %}`${{CF_PIPELINE_NAME}}`{% endraw %} | The full path of the pipeline, i.e. "project/pipeline" | +| {% raw %}`${{CF_VOLUME_NAME}}`{% endraw %} | Refers to the [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) between [freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/). Normally you only need to define this in [compositions]({{site.baseurl}}/docs/pipelines/steps/composition/). In freestyle steps, it is automatically present without any extra configuration. | +| {% raw %}`${{CF_VOLUME_PATH}}`{% endraw %} | Refers to the mounted path of the [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) inside a Freestyle container. In the current implementation it expands to `/codefresh/volume`. | +| {% raw %}`${{CF_BUILD_TRIGGER}}`{% endraw %} | Will be an indication of the current build was triggered: *build: The build was triggered from the build button* webhook: The build was triggered from a control version webhook | +| {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | The build id. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_ID}}`{% endraw %} | +| {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | The timestamp the build was created. Note: use this variable as string with quotes to tag the image {% raw %}`${{CF_BUILD_TIMESTAMP}}`{% endraw %} | +| {% raw %}`${{CF_BUILD_URL}}`{% endraw %} | The URL to the build in Codefresh | +| {% raw %}`${{CF_PIPELINE_NAME}}`{% endraw %} | The full path of the pipeline, i.e. "project/pipeline" | | {% raw %}`${{CF_STEP_NAME}}`{% endraw %} | the name of the step, i.e. "MyUnitTests" | -| {% raw %}`${{CF_URL}}`{% endraw %} | The URL of Codefresh system | -| {% raw %}`${{CI}}`{% endraw %} | The value is always `true` | -| {% raw %}`${{CF_KUBECONFIG_PATH}}`{% endraw %} | Path to injected kubeconfig if at least one Kubernetes cluster [is configured]({{site.baseurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/). You can easily run [custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) since it is automatically setup by Codefresh in all pipelines. | -| Any variable specified in the pipeline settings | For example, if you configure the pipeline settings with a variable named PORT, you can put the variable in your YAML build descriptor as {% raw %}`${{PORT}}`{% endraw %}. | +| {% raw %}`${{CF_URL}}`{% endraw %} | The URL of Codefresh system | +| {% raw %}`${{CI}}`{% endraw %} | The value is always `true` | +| {% raw %}`${{CF_KUBECONFIG_PATH}}`{% endraw %} | Path to injected kubeconfig if at least one Kubernetes cluster [is configured]({{site.baseurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/). You can easily run [custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) since it is automatically setup by Codefresh in all pipelines. | +| Any variable specified in the pipeline settings | For example, if you configure the pipeline settings with a variable named PORT, you can put the variable in your YAML build descriptor as {% raw %}`${{PORT}}`{% endraw %}. | -## Context Related Variables -Context related variables are created dynamically during the workflow execution and according to the used steps. +## Context-related Variables +Context-related variables are created dynamically during the workflow execution and according to the used steps. {: .table .table-bordered .table-hover} -| Variable | Description | -| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Variable | Description | +| ------------------------------------------------- | ------------------------------------------------------ | | **Working Directories** | For example, you can set the working directory of step `A` with a variable named after a previously executed step, step `B`. Therefore, setting step `A` with {% raw %}`working-directory:${{B}}`{% endraw %} means that step `A` executes in the same working directory as step `B`. | | **Images** | You can set the candidate field of the push step with a variable named after a previously executed build step. Since the details of a created image are not necessarily known ahead of time, the variable can create an association to an optionally dynamic image name. Therefore, setting push step `A` with {% raw %}`candidate:${{B}}`{% endraw %} means that step `A` will push the image built by step `B`. Note that this capability works only for `candidate` and `image` fields in Codefresh steps. | @@ -147,7 +147,7 @@ In the example above you can see the `MyAppDockerImage` variable that denotes a ## Step variables -Every [step]({{site.baseurl}}/docs/codefresh-yaml/steps/) in a Codefresh pipeline also exposes several built-in variables. You can access them via the global `steps` parent variable. +Every [step]({{site.baseurl}}/docs/pipelines/steps/) in a Codefresh pipeline also exposes several built-in variables. You can access them via the global `steps` parent variable. * Each step creates a variable based on the name of the step. You can then use the members of each variable for status conditions such as: `steps.MyUnitTests.result == 'error'` for a step called `MyUnitTests`. * To access variables that have a non-standard (i.e. only alphanumeric and _ characters) names, use the Variable() function. @@ -157,9 +157,9 @@ Every [step]({{site.baseurl}}/docs/codefresh-yaml/steps/) in a Codefresh pipelin Variables that are created by steps can have members. The members depend on the step type. For example if you have a build step named `myBuildStep` you can get the ID of the docker image that gets created with {% raw %}`echo ${{steps.myBuildStep.imageId}}`{% endraw %} {: .table .table-bordered .table-hover} -| Step Type | Members | -| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| All step types | {::nomarkdown}
  • name
  • type
  • description
  • workingDirectory
  • result
{:/} | +| Step Type | Members | +| ----------------------- | -------------------------------------- | +| All step types | {::nomarkdown}
  • name
  • type
  • description
  • workingDirectory
  • result
{:/} | [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | - | | [**Composition**]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) | - | | [**Build**]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | {::nomarkdown}
  • imageName
  • imageTagName
  • imageId
{:/} | From 9371df71bb1751e9c2c8d5444dc7559b5cd56d95 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Sun, 4 Dec 2022 09:39:44 +0200 Subject: [PATCH 4/8] Update pipeline topics Fixed x-refs, formatting, and ported pipeline settings from Classic and moved to Pipeline bucket --- _docs/pipelines/advanced-workflows.md | 67 +++++++------- _docs/pipelines/build-status.md | 11 +-- _docs/pipelines/debugging-pipelines.md | 31 +++---- _docs/pipelines/monitoring-pipelines.md | 39 ++++---- _docs/pipelines/pipeline-caching.md | 51 +++++------ _docs/pipelines/pipeline-settings.md | 86 ++++++++++++++++++ _docs/pipelines/running-pipelines-locally.md | 14 ++- _docs/pipelines/secrets-store.md | 28 +++--- _docs/pipelines/shared-configuration.md | 17 ++-- _docs/pipelines/variables.md | 24 +++-- _docs/pipelines/what-is-the-codefresh-yaml.md | 72 +++++++-------- .../pause-pipeline-enabled.png | Bin 0 -> 23131 bytes .../pipeline-settings-ui.png | Bin 0 -> 122724 bytes 13 files changed, 256 insertions(+), 184 deletions(-) create mode 100644 _docs/pipelines/pipeline-settings.md create mode 100644 images/pipeline/pipeline-settings/pause-pipeline-enabled.png create mode 100644 images/pipeline/pipeline-settings/pipeline-settings-ui.png diff --git a/_docs/pipelines/advanced-workflows.md b/_docs/pipelines/advanced-workflows.md index 209a339d..1314ff7f 100644 --- a/_docs/pipelines/advanced-workflows.md +++ b/_docs/pipelines/advanced-workflows.md @@ -1,32 +1,35 @@ --- -title: "Advanced Workflows with Parallel steps" -description: "Learn how to create complex workflows in Codefresh with step dependencies" +title: "Advanced workflows with parallel steps" +description: "Create complex workflows in Codefresh with step dependencies" group: codefresh-yaml toc: true --- -Codefresh is very flexible when it comes to pipeline complexity and depth. You can easily create: +Codefresh is very flexible when it comes to pipeline complexity and depth. - * Sequential pipelines where step order is same as the listing order in yaml (simple) +You can easily create: + * Sequential pipelines where step order is the same as the listing order in YAML (simple) * Sequential pipelines that have some parallel parts (intermediate) * Parallel pipelines where step order is explicitly defined (advanced) With the parallel execution mode, you can define complex pipelines with fan-in/out configurations capable of matching even the most complicated workflows within an organization. ->Notice that in Codefresh parallel execution is unrelated with [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/). Stages are only a way to visually organize your pipeline steps. The actual execution is independent from the visual layout in the logs view. +>In Codefresh, parallel execution is unrelated to [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/). Stages are only a way to visually organize your pipeline steps. The actual execution is independent from the visual layout in the logs view. Before going any further make sure that you are familiar with the [basics of Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). Codefresh offers two modes of execution: -1. Sequential Mode (which is the default) -1. Parallel Mode +1. Sequential mode (which is the default) +1. Parallel mode ## Sequential execution mode The sequential mode is very easy to understand and visualize. -In Sequential mode the Codefresh execution engine starts from the first step defined at the top of the `codefresh.yml` file and executes all steps one by one going down to the end of the file. A step is either executed or skipped according to its conditions. The condition for each step is only examined **once**. +In sequential mode, the Codefresh execution engine starts from the first step defined at the top of the `codefresh.yml` file, and executes all steps one by one going down to the end of the file. A step is either executed or skipped according to its conditions. + +>The condition for each step is only examined **once**. `YAML` {% highlight yaml %} @@ -49,7 +52,7 @@ steps: {% endraw %} {% endhighlight %} -Here we have two steps, one that creates a Docker image and a second one that runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) inside it. The order of execution is the same order of the steps in the YAML file. This means that unit tests will always run after the Docker image creation. +Here we have two steps, one that creates a Docker image and a second one that runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) inside it. The order of execution is identical to the order of the steps in the YAML file. This means that unit tests will always run after the Docker image creation. Notice that the line `mode: sequential` is shown only for illustration purposes. Sequential mode is the default, and therefore this line can be omitted. @@ -91,9 +94,9 @@ The final order of execution will be 1. Task 2A and Task2B at the same time 1. Task 3 -This is the recommended way to start using parallelism in your Codefresh pipelines and it will be enough for most scenarios that require parallelism. +This is the recommended way to start using parallelism in your Codefresh pipelines. It is sufficient for most scenarios that require parallelism. ->Notice that step names should be unique within the same pipeline. The parent and child steps should NOT share the same name. +>The step names must be unique within the same pipeline. The parent and child steps should NOT share the same name. ### Example: pushing multiple Docker images in parallel @@ -143,8 +146,8 @@ steps: The order of execution is the following: -1. MyAppDockerImage ([build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/)) -1. jfrog_PushingTo_jfrog_BintrayRegistry, PushingToGoogleRegistry, PushingToDockerRegistry ([push steps]({{site.baseurl}}/docs/codefresh-yaml/steps/push/)) +1. MyAppDockerImage ([build step]({{site.baseurl}}/docs/pipelines/steps/build/)) +1. jfrog_PushingTo_jfrog_BintrayRegistry, PushingToGoogleRegistry, PushingToDockerRegistry ([push steps]({{site.baseurl}}/docs/pipelines/steps/push/)) The pipeline view for this yaml file is the following. @@ -158,10 +161,10 @@ caption="Parallel Docker push" max-width="80%" %} -As you can see we have also marked the steps with [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) so that we get a visualization that matches the execution. +As you can see we have also marked the steps with [stages]({{site.baseurl}}/docs/pipelines/stages/) so that we get a visualization that matches the execution. -### Example: running multiple test suites in parallel +### Example: Running multiple test suites in parallel All types of steps can by placed inside a parallel phase. Another common use case would be the parallel execution of [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) for unit/integration tests. @@ -264,7 +267,7 @@ In the example above we have explicitly defined that even if the integration or ### Shared Codefresh volume and race conditions -In any pipeline step, Codefresh automatically attaches a [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that is used to transfer artifacts between steps. The same volume is also shared between steps that run in parallel. +In any pipeline step, Codefresh automatically attaches a [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) that is used to transfer artifacts between steps. The same volume is also shared between steps that run in parallel. Here is an example where two parallel steps are writing two files. After they finish execution, we list the contents of the project folder. @@ -524,10 +527,10 @@ of matrix variations can quickly grow if you add too many dimensions. Notice that, as with the `scale` syntax, the defined values/properties are merged between parent step (`MyUnitTests` in the example above) and children steps. For example, if you set an environment variable on the parent and also on child matrix steps , the result will a merged environment where all values are available. -## Parallel pipeline mode -> If you use parallel pipeline mode, you _cannot_ use _implicit parallel steps_. +## Parallel pipeline execution +> If you use parallel execution mode for pipelines, you _cannot_ use _implicit parallel steps_. -To activate advanced parallel mode for the whole pipeline you need to declare it explicitly at the root of the `codefresh.yml` file: +To activate advanced parallel mode for the whole pipeline, you need to declare it explicitly at the root of the `codefresh.yml` file: ``` version: '1.0' @@ -536,14 +539,14 @@ steps: [...] ``` -In full parallel mode, the order of steps inside the `codefresh.yml` is **not** affecting the order of execution at all. The Codefresh pipeline engine instead: +In full parallel mode, the order of steps inside the `codefresh.yml` **does not** affect the order of execution at all. The Codefresh pipeline engine instead: -1. Evaluates all steps conditions *at the same* time +1. Evaluates all step-conditions *at the same* time 2. Executes those that have their requirements met 3. Starts over with the remaining steps -4. Stops when there no more steps to evaluate +4. Stops when there are no more steps to evaluate -This means that in parallel mode the conditions of a step are evaluated **multiple times** as the Codefresh execution engine is trying to find which steps it should run next. This implication is very important when you try to understand the order of step execution. +This means that in parallel mode the conditions of a step are evaluated **multiple times** as the Codefresh execution engine tries to find which steps it should run next. This implication is very important when you try to understand the order of step execution. Notice also that in parallel mode, if you don't define any step conditions, Codefresh will try to run **all** steps at once, which is probably not what you want in most cases. @@ -551,7 +554,7 @@ With parallel mode you are expected to define the order of steps in the yaml fil In the next sections we describe how you can define the steps dependencies in a parallel pipeline. -### Single Step Dependencies +### Single step dependencies At the most basic level, you can define that a step *depends on* the execution of another step. This dependency is very flexible as Codefresh allows you run a second step once: @@ -666,7 +669,7 @@ If you run the pipeline you will see that Codefresh automatically understands th Also notice the `fail_fast: false` line in the unit tests. By default, if *any* steps fails in a pipeline the whole pipeline is marked as a failure. With the `fail_fast` directive we can allow the pipeline to continue so that other steps that depend on the failed step can still run even. -### Multiple Step dependencies +### Multipl step dependencies A pipeline step can also depend on multiple other steps. @@ -789,11 +792,11 @@ steps: In this case Codefresh will make sure that cleanup happens only when both unit and integration tests are finished. -### Custom Steps Dependencies +### Custom step dependencies -For maximum flexibility you can define a custom conditional for a step. +For maximum flexibility you can define a custom condition for a step. -It is hard to describe all possible cases, because Codefresh support a [mini DSL]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) for conditions. All examples mentioned in [conditional execution]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) are still valid in parallel pipelines. +It is hard to describe all possible cases, because Codefresh supports a [mini DSL]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/#condition-expression-syntax) for conditions. All examples mentioned in conditional execution are still valid in parallel pipelines. For example, run this step only if a PR is opened against the production branch: @@ -956,11 +959,9 @@ The possible values for `workflow.result` are: * `success` -## What to read next - -* [Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) -* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Pipeline/Step hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) +## Related articles +[Variables in pipelines]({{site.baseurl}}/docs/pipelines/variables/) +[Hooks in pipelines]({{site.baseurl}}/docs/pipelines/hooks/) diff --git a/_docs/pipelines/build-status.md b/_docs/pipelines/build-status.md index 98d48f27..02d9e897 100644 --- a/_docs/pipelines/build-status.md +++ b/_docs/pipelines/build-status.md @@ -142,10 +142,9 @@ max-width="90%" Your visitors can also click on each individual pipeline step and see the logs for that step only. -If you are using Codefresh to manage a public project, you should also use the capability to [trigger builds from external forks]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/#support-for-building-pull-requests-from-forks). +If you are using Codefresh to manage a public project, you should also use the capability to [trigger builds from external forks]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/#support-for-building-pull-requests-from-forks). -## What to read next - -* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [Monitoring pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/monitoring-pipelines/) +## Related articles +[Introduction to Codefresh pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Monitoring pipelines]({{site.baseurl}}/docs/pipelines/monitoring-pipelines/) diff --git a/_docs/pipelines/debugging-pipelines.md b/_docs/pipelines/debugging-pipelines.md index 90b36301..9ece11c5 100644 --- a/_docs/pipelines/debugging-pipelines.md +++ b/_docs/pipelines/debugging-pipelines.md @@ -1,13 +1,12 @@ --- -title: "Debugging Codefresh pipelines" +title: "Debugging pipelines" description: "How to pause and inspect pipelines" group: configure-ci-cd-pipeline toc: true --- -In addition to [running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) Codefresh also allows you to debug pipelines by stopping their execution and inspecting manually their state (files, environment variables, tools etc.) +In addition to [running pipelines locally]({{site.baseurl}}/docs/pipelines/running-pipelines-locally/), Codefresh also allows you to debug pipelines by stopping their execution and inspecting manually their state (files, environment variables, tools etc.) -## How Debugging works The Codefresh pipeline debugger works similar to your IDE debugger. You can place breakpoints on one or more pipeline steps and once the pipeline hits one of them, it will stop. You will then get a terminal like interface inside your pipeline step where you can run any commands that you wish in order to understand the state of the container. @@ -22,7 +21,7 @@ The Codefresh pipeline debugger works similar to your IDE debugger. You can plac max-width="70%" %} -There are several option for defining exactly when a step will stop. +There are several options for defining exactly when a step will stop. ## Entering the debugger mode @@ -67,7 +66,7 @@ Now you are ready to place breakpoints in steps. ## Placing breakpoints -Once the debugging mode is active all pipeline steps will get an extra breakpoint icon on the far right of their box. +Once the debugging mode is active, all pipeline steps will get an extra breakpoint icon on the far right of their box. {% include image.html @@ -83,11 +82,11 @@ Once the debugging mode is active all pipeline steps will get an extra breakpoin You can click on this icon and define a breakpoint for this particular step. You have the following options * *Before* - place a breakpoint before the step is initialized -* *Override* - place a breakpoint after the step has initialized but before its execution ([freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/)) +* *Override* - place a breakpoint after the step has initialized but before its execution ([freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/)) * *After* - place a breaking point after the step has finished execution. You can choose multiple debugging phases. In most cases the `Override` option is the most useful one. The `before` phase allows you to inspect -a pipeline step even before [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) are up. +a pipeline step even before [service containers]({{site.baseurl}}/docs/pipelines/service-containers/) are up. The `after` phase is useful if you want to verify files or variables after a step has finished its execution but before the next step starts. @@ -112,12 +111,12 @@ You can now manually type commands to inspect your container. If your Codefresh * `printenv` to see environment variables * `cat` to read files * `top` to see what is running -* `export` and [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) to create environment variables +* `export` and [cf_export]({{site.baseurl}}/docs/pipelines/variables/#using-cf_export-command) to create environment variables * `exit` to finish the debugging session If you have placed a breakpoint in the `override` phase of a freestyle step then the container image is the same as the one defined in the step. Therefore you can execute all tools that you have placed in the image (e.g. compilers, linters, test frameworks etc.) -In all cases the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automounted so you can examine your source code or any other intermediate artifacts placed in your project folder or the pipeline cache. +In all cases the [shared Codefresh volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) is automounted so you can examine your source code or any other intermediate artifacts placed in your project folder or the pipeline cache. If the breakpoint is on a `before` or `after` phase, the command line terminal is powered by an [alpine](https://alpinelinux.org/) image. The image has already useful tools such as `wget`, `nc` and `vi`. If you have the advanced debugging capabilities in your Codefresh plan you can then install additional tools on your own directly in the terminal with [apk](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management). Examples: @@ -245,13 +244,7 @@ The debugger windows needs some extra tools in a docker image in order to work ( If you get the message *your linux distribution is not supported* please contact us so that we can examine your docker image and make sure it is compatible with the Codefresh debugger. - - - - -## What to read next - -* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Running pipelines locally]({{site.baseurl}}/docs/pipelines/running-pipelines-locally/) diff --git a/_docs/pipelines/monitoring-pipelines.md b/_docs/pipelines/monitoring-pipelines.md index 9aae7333..c5bab5ea 100644 --- a/_docs/pipelines/monitoring-pipelines.md +++ b/_docs/pipelines/monitoring-pipelines.md @@ -6,9 +6,9 @@ toc: true --- -All pipeline activity in Codefresh can be viewed on the *Builds* tab. -There is one global view from the left-side menu that shows builds for all projects -across your organization and a project-based view from the settings inside an individual project. +All pipeline activity in Codefresh can be viewed in the *Builds* tab. +* The global build view shows builds for all projects across your organization +* The project-based view from the settings inside an individual project shows the builds for the selected project Both views have the same controls and filters. @@ -152,7 +152,7 @@ There are also extra options if you click the small "3-dot" menu button on the r - View the logs - View the YAML -- View or add [annotations]({{site.baseurl}}/docs/codefresh-yaml/annotations/) +- View or add [annotations]({{site.baseurl}}/docs/pipelines/annotations/) - View the images produced (and consequently launch an on-demand [test environment]({{site.baseurl}}/docs/getting-started/on-demand-environments/#launching-a-docker-image-using-codefresh)) Notice that if you restart a pipeline it will trigger with the exact settings it *originally* had. So @@ -182,7 +182,7 @@ Each section in this screen corresponds to each pipeline step. There are two spe * *Initializing Process* * *Cloning Main Repository* -These are Codefresh built-in steps and will appear for most builds (you can also create a pipeline that doesn't clone a git repository by default). The rest of the step names depend on your `codefresh.yml` (or the default step names provided by Codefresh). The different columns take the names from the defined [pipeline stages]({{site.baseurl}}/docs/codefresh-yaml/stages/). +These are Codefresh built-in steps and will appear for most builds (you can also create a pipeline that doesn't clone a git repository by default). The rest of the step names depend on your `codefresh.yml` (or the default step names provided by Codefresh). The different columns take the names from the defined [pipeline stages]({{site.baseurl}}/docs/pipelines/stages/). ### Viewing status for pipeline steps @@ -272,7 +272,7 @@ The variables are grouped by granularity, starting with the global project-level * Pipeline * Trigger -A variable with a strikethrough indicates an override by the same variable in a lower-level group. For rules on precedence and overrides for variables in builds, see [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/). +A variable with a strikethrough indicates an override by the same variable in a lower-level group. For rules on precedence and overrides for variables in builds, see [Variables]({{site.baseurl}}/docs/pipelines/variables/). >Notes: * Variables exported across steps with `cf_export` are not identified as `cf-exported` variables in the list. @@ -369,7 +369,7 @@ caption="Restart a pipeline" max-width="70%" %} ->It is important to note that "Restart from beginning" will restart a pipeline with the **same** state that it had in its original execution (including the original git commit). If you want to execute a pipeline again with a new state instead, you need to use the *Run* button in the [pipeline editor]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#using-the-inline-pipeline-editor) and selecting any of the available [triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/). +>It is important to note that "Restart from beginning" will restart a pipeline with the **same** state that it had in its original execution (including the original git commit). If you want to execute a pipeline again with a new state instead, you need to use the *Run* button in the [pipeline editor]({{site.baseurl}}/docs/pipelines/pipelines/#using-the-inline-pipeline-editor) and selecting any of the available [triggers]({{site.baseurl}}/docs/pipelines/triggers/). @@ -389,15 +389,15 @@ max-width="70%" >Notice again that restarting a pipeline from a failed step means restarting the pipeline with the **same** state that it had at the point in time (including the original git commit). -If your pipeline has some flaky steps, you can also use the [retry syntax]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#retrying-a-step) in your yaml instead of restarting them manually each time they fail. +If your pipeline has some flaky steps, you can also use the [retry syntax]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/#retrying-a-step) in your yaml instead of restarting them manually each time they fail. -## Monitoring Pipelines outside the Codefresh UI +## Monitoring pipelines outside the Codefresh UI You don't always have to be in the Codefresh UI in order to monitor the status of your builds. -### Monitoring Pipelines that check Pull requests +### Monitoring pipelines that check Pull Requests One of the most important roles of a CI platform is to automatically update the status of a GIT Pull request with the result @@ -413,7 +413,7 @@ caption="Pull Request Status (click image to enlarge)" max-width="50%" %} -If you have setup a [GIT trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) in Codefresh then by default this happens automatically without any other configuration +If you have setup a [GIT trigger]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) in Codefresh then by default this happens automatically without any other configuration for all automated commits (that are coming from webhooks). If you start a build manually then by default the git status will **not** be updated (i.e. the result of the pipeline @@ -436,9 +436,9 @@ This way the pipeline status *will* change the build status even with manual bui The same behavior is also available to the [Codefresh CLI](https://codefresh-io.github.io/cli/pipelines/run-pipeline/). In that case use the parameter `--enable-notifications` to specify if manually triggering a build will also change the GIT status. -For open source projects you also have the ability to [trigger builds from external forks]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/#support-for-building-pull-requests-from-forks). +For open source projects you also have the ability to [trigger builds from external forks]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/#support-for-building-pull-requests-from-forks). -### Viewing Pipeline status from text/html files +### Viewing pipeline status from text/html files Codefresh also supports build badges that allow you to show the status of a Pipeline in Text files or web pages. @@ -453,12 +453,11 @@ caption="Codefresh build badges" max-width="100%" %} -See the [build badges page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) for more information. +See the [build badges page]({{site.baseurl}}/docs/pipelines/build-status/) for more information. -## What to read next - -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Test report]({{site.baseurl}}/docs/configure-ci-cd-pipeline/test-reports/) -* [Status badges]({{site.baseurl}}/docs/configure-ci-cd-pipeline/build-status/) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Test report]({{site.baseurl}}/docs/pipelines/test-reports/) +[Status badges]({{site.baseurl}}/docs/pipelines/build-status/) diff --git a/_docs/pipelines/pipeline-caching.md b/_docs/pipelines/pipeline-caching.md index acd9ecc8..95ff6dd8 100644 --- a/_docs/pipelines/pipeline-caching.md +++ b/_docs/pipelines/pipeline-caching.md @@ -1,5 +1,5 @@ --- -title: "Pipeline caching" +title: "Caching in pipelines" description: "Faster builds with Codefresh caching" group: configure-ci-cd-pipeline toc: true @@ -15,11 +15,11 @@ Here is a quick overview of all types of caching used in a Codefresh pipeline: {: .table .table-bordered .table-hover} | Caching mechanism | Activation | Used in | Comments | | -------------- | ---------------------------- |-------------------------| -------------------------| -| Distributed Docker step/image caching | Automatic | All pipeline [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) | | -| Distributed Docker layer caching | Automatic | Pipeline [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | Mimics local Docker layer cache| +| Distributed Docker step/image caching | Automatic | All pipeline [steps]({{site.baseurl}}/docs/pipelines/steps/) | | +| Distributed Docker layer caching | Automatic | Pipeline [build steps]({{site.baseurl}}/docs/pipelines/steps/build/) | Mimics local Docker layer cache| | Caching from previous built image | Automatic | Pipeline build steps | Distributed version of `--cache-from`| | Docker registry caching | Automatic | Pipeline build steps | Works for all [connected Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/)| -| Traditional build caching | Automatic/manual | Pipeline [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | See notes for [parallel builds]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/)| +| Traditional build caching | Automatic/manual | Pipeline [freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/) | See notes for [parallel builds]({{site.baseurl}}/docs/pipelines/advanced-workflows/)| All these caching mechanisms are enabled by default and you can [freely disable them]({{site.baseurl}}/docs/troubleshooting/common-issues/disabling-codefresh-caching-mechanisms/) if you encounter any issues with caching. @@ -27,7 +27,7 @@ Let's see these caches in order and how to use them effectively. ## Distributed Docker image caching -This is the simplest mode of caching available. All Codefresh steps [are in fact docker images]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/). Once a pipeline runs for the first time, Codefresh will pull all required images from their registries (either public or private) and will cache them for the next build: +This is the simplest mode of caching available. All Codefresh steps [are in fact docker images]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/). Once a pipeline runs for the first time, Codefresh will pull all required images from their registries (either public or private) and will cache them for the next build: {% include image.html @@ -39,7 +39,7 @@ caption="Caching pipeline steps" max-width="60%" %} -The next time the pipeline runs all images will be fetched from cache. This includes built-in steps (e.g the [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/)), custom steps from [the marketplace](https://codefresh.io/steps/) or your own [dynamic pipeline steps]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#creating-docker-images-dynamically-as-build-tools). +The next time the pipeline runs all images will be fetched from cache. This includes built-in steps (e.g the [clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/)), custom steps from [the marketplace](https://codefresh.io/steps/) or your own [dynamic pipeline steps]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#creating-docker-images-dynamically-as-build-tools). This cache mechanism is completely automatic and is not user configurable. Some ways that you can affect it are: @@ -48,7 +48,7 @@ This cache mechanism is completely automatic and is not user configurable. Some * Using small images in the pipeline will make caching/restoring of pipeline steps much faster. -You can see in the [pipeline build logs]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) if the images of your steps are found in cache or not. Here is an example of a cache hit: +You can see in the [pipeline build logs]({{site.baseurl}}/docs/pipelines/steps/build/) if the images of your steps are found in cache or not. Here is an example of a cache hit: {% include image.html lightbox="true" @@ -75,7 +75,7 @@ This cache mechanism is applicable to all Codefresh pipelines and steps. ## Distributed Docker layer caching -This type of caching is **only** applicable to [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) and mimics the ways docker layer caching behaves locally on your workstation. +This type of caching is **only** applicable to [build steps]({{site.baseurl}}/docs/pipelines/steps/build/) and mimics the ways docker layer caching behaves locally on your workstation. When you build images locally, Docker will cache intermediate layers making future builds much faster. You can see when caches are used in your build logs. @@ -127,7 +127,7 @@ max-width="60%" With the distributed docker layer cache all build nodes are now equal. Any of the available nodes can pick your next pipeline build as all of them have access to all the previous docker filesystem layers. -You can see if this cache is used in your [pipeline logs]({{site.baseurl}}/docs/codefresh-yaml/steps/build/): +You can see if this cache is used in your [pipeline logs]({{site.baseurl}}/docs/pipelines/steps/build/): {% include image.html lightbox="true" @@ -163,7 +163,7 @@ Basically, if your Dockerfile is already optimized on your local workstation, it ## Docker registry caching -This is a caching mechanism unique to Codefresh and applicable only to [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) when any of [connected Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) is used. +This is a caching mechanism unique to Codefresh and applicable only to [build steps]({{site.baseurl}}/docs/pipelines/steps/build/) when any of [connected Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) is used. Codefresh will check the internal Docker registry *before* a build step and if the exact same image is found (using the image hash), it will skip the build step completely: @@ -182,7 +182,7 @@ You can take advantage of this mechanism by [not mixing deployment docker images ## Traditional build caching -If you have read the [introduction to pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) page you will already be familiar with the shared volume that is automatically mounted on all pipeline steps. This volume is not only used for data exchange between steps of the same pipeline, but is also stored/fetched for each subsequent build as well. +If you have read the [introduction to pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines) page you will already be familiar with the shared volume that is automatically mounted on all pipeline steps. This volume is not only used for data exchange between steps of the same pipeline, but is also stored/fetched for each subsequent build as well. {% include image.html lightbox="true" @@ -195,9 +195,9 @@ max-width="90%" This means that unlike other CI solutions where you have to manually describe what folder you wish to cache, in Codefresh **everything that exists in `/codefresh/volume` and its subfolders is automatically cached between different builds** of the same pipeline. The volume mounting and caching/restoring process is completely automatic. You don't need any configuration about it. -The main choice that you have is which files to place on the volume. For example, Node.js uses the folder `node_modules` for its dependencies which are placed under the project folder [which is automatically placed under the volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code). So all contents of `node_modules` will be cached by default without any further action on your part. +The main choice that you have is which files to place on the volume. For example, Node.js uses the folder `node_modules` for its dependencies which are placed under the project folder [which is automatically placed under the volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#cloning-the-source-code). So all contents of `node_modules` will be cached by default without any further action on your part. ->Note that if you are using [Codefresh on-prem]({{site.baseurl}}/docs/administration/codefresh-on-prem/), this kind of caching is not available for the built-in runtime and you need to use the [Codefresh Runner]({{site.baseurl}}/docs/administration/codefresh-runner/) +>Note that if you are using [Codefresh on-prem]({{site.baseurl}}/docs/installation/codefresh-on-prem/), this kind of caching is not available for the built-in runtime and you need to use the [Codefresh Runner]({{site.baseurl}}/docs/installation/codefresh-runner/) with your own runtime to activate volume caching. The simplest way to see this caching mechanism in action is this pipeline: @@ -222,7 +222,7 @@ steps: If you run this pipeline multiple times you will see multiple entries in the file `sample.txt`. ->Note that if you run concurrent builds too quickly after one another, the Codefresh Volume will refresh [from scratch]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/#issues-with-parallel-builds-and-parallel-pipelines) instead of being cached between builds. +>Note that if you run concurrent builds too quickly after one another, the Codefresh Volume will refresh [from scratch]({{site.baseurl}}/docs/pipelines/pipeline-caching/#issues-with-parallel-builds-and-parallel-pipelines) instead of being cached between builds. {% include image.html lightbox="true" @@ -237,18 +237,18 @@ Notice also the complete lack of `volume` directives in the `codefresh.yml` file Some important points on this caching mechanism: -* The volume is handled and managed by Codefresh in a completely transparent manner. You **DO NOT** need any `volume` directives in your pipelines to take advantage of it. The volume is even present in [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for integration tests. -* On each build the [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) will purge/delete everything that is not placed in `.gitignore`. So make sure that your `.gitignore` files contain all the things that you want to see cached (e.g. `node_modules`) +* The volume is handled and managed by Codefresh in a completely transparent manner. You **DO NOT** need any `volume` directives in your pipelines to take advantage of it. The volume is even present in [service containers]({{site.baseurl}}/docs/pipelines/service-containers/) for integration tests. +* On each build the [clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) will purge/delete everything that is not placed in `.gitignore`. So make sure that your `.gitignore` files contain all the things that you want to see cached (e.g. `node_modules`) * If you use the SAAS version of Codefresh, volumes will be reused across all your account pipelines. If you use the On-prem or Hybrid version of Codefresh, pipeline volumes can be scoped to different pipelines or triggers as well * You need at least one build of your pipeline in order for the cache mechanism to take any effect. -* The volume is **NOT available** in [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080). There is no folder `/codefresh/volume` inside a Dockerfile for you to access. +* The volume is **NOT available** in [build steps]({{site.baseurl}}/docs/pipelines/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080). There is no folder `/codefresh/volume` inside a Dockerfile for you to access. * This is the only caching mechanism that is not related to Docker images. So if you compile/package a traditional application with Codefresh that is not packaged as a Docker image this is the only way to get faster builds. See also a [full example]({{site.baseurl}}/docs/yaml-examples/examples/shared-volumes-between-builds/) that uses the volume at [https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds](https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds). ### Caching folders which are outside your project folder -By default if you checkout a Git project named `foo`, the source code [is placed under]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) `/codefresh/volume/foo`. This means that with zero configuration the following things are cached: +By default if you checkout a Git project named `foo`, the source code [is placed under]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#cloning-the-source-code) `/codefresh/volume/foo`. This means that with zero configuration the following things are cached: * your source code of `foo` project * all dependencies under the project folder (e.g. `foo/node_modules`) @@ -271,9 +271,9 @@ In practice, this means that you need to look at the documentation of your build Codefresh supports two forms of parallelism, parallel steps within the same pipeline and parallel pipelines (as well as concurrent builds). -All parallel steps inside the same pipeline use the same volume. Codefresh [does not perform any conflict detection in that case]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#shared-codefresh-volume-and-race-conditions). +All parallel steps inside the same pipeline use the same volume. Codefresh [does not perform any conflict detection in that case]({{site.baseurl}}/docs/pipelines/advanced-workflows/#shared-codefresh-volume-and-race-conditions). -For concurrent builds of the same pipeline, notice that if you make too many commits very fast (triggering a second build while the previous one is still running), Codefresh will allocate a brand new volume for the subsequent builds. This will force all builds to start with a clean shared volume, resulting in longer build times. Be sure to set your [build termination settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) correctly. +For concurrent builds of the same pipeline, notice that if you make too many commits very fast (triggering a second build while the previous one is still running), Codefresh will allocate a brand new volume for the subsequent builds. This will force all builds to start with a clean shared volume, resulting in longer build times. Be sure to set your [build termination settings]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-settings) correctly. {% include image.html lightbox="true" @@ -307,9 +307,8 @@ If you run a pipeline very infrequently it is possible to suffer many cache miss If you run the [hybrid or on-prem versions]({{site.baseurl}}/docs/enterprise/installation-security/) of Codefresh, then your system administrator is responsible for fine-tuning the cache settings. -## What to read next - -* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Parallel pipelines]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +## Related articles +[Introduction to Codefresh pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +* [Parallel pipelines]({{site.baseurl}}/docs/pipelines/advanced-workflows/) diff --git a/_docs/pipelines/pipeline-settings.md b/_docs/pipelines/pipeline-settings.md new file mode 100644 index 00000000..6b857fd3 --- /dev/null +++ b/_docs/pipelines/pipeline-settings.md @@ -0,0 +1,86 @@ +--- +title: "Global settings for piplines" +description: "Define global options for pipeline templates, yaml sources and approval behavior" +group: administration +toc: true +--- + +To access your global pipeline settings navigate to [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings) or click on *Account settings* on the left sidebar and then choose *Pipeline settings* item on the next screen. + +On this page, you can define global parameters for the whole Codefresh account regarding pipeline options. Users can still override some of these options for individual pipelines. + +{% include image.html +lightbox="true" +file="/images/administration/pipeline-settings/pipeline-settings-ui.png" +url="/images/administration/pipeline-settings/pipeline-settings-ui.png" +alt="Pipeline settings" +caption="Pipeline settings" +max-width="80%" +%} + + +## Pause pipeline executions + +Pause builds for pipelines at the account level, for example, during maintenance. + +* **Pause build execution** is disabled by default. +* When enabled: + * New pipelines in the account are paused immediately. + * Existing pipelines with running builds are paused only after the builds have completed execution. +* Paused pipelines are set to status Pending, and remain in this status until **Pause build execution** is manually disabled for the account. + +{% include image.html +lightbox="true" +file="/images/pipeline/pipeline-settings/pause-pipeline-enabled.png" +url="/images/pipeline/pipeline-settings/pause-pipeline-enabled.png" +alt="Pause Build Execution pipeline setting enabled" +caption="Pause Build Execution pipeline setting enabled" +max-width="80%" +%} + +## Template section + +Here you can define global template behavior. The options are: + +* Enable [pipeline templates]({{site.baseurl}}/docs/docs/pipelines/pipelines/#using-pipeline-templates) for users. If this is enabled some pipelines can be marked as templates and users can still select them when creating a new pipeline. +* Decide if users can clone an existing pipeline (along with its triggers and associated parameters) when [creating a new pipeline]({{site.baseurl}}/docs/docs/pipelines/pipelines/#creating-new-pipelines). + +Note that templates are simply normal pipelines “marked” as a template. There is no technical difference between templates and actual pipelines. + +## Pipeline YAML section + +Here you can restrict the sources of pipeline YAML that users can select. The options are: + +* Enable/Disable the [inline editor]({{site.baseurl}}/docs/docs/pipelines/pipelines/#using-the-inline-pipeline-editor) where YAML is stored in Codefresh SaaS +* Enable/disable pipeline YAML from connected Git repositories +* Enable/disable pipeline YAML from [external URLs]({{site.baseurl}}/docs/docs/pipelines/pipelines/#loading-codefreshyml-from-version-control) + +You need to allow at least one of these options so that users can create new pipelines. We suggest leaving the first option enabled when users are still learning about Codefresh and want to experiment. + +## Advanced pipeline options + +Here you can set the defaults for advanced pipeline behavior. The options are: + +* [Keep or discard]({{site.baseurl}}/docs/pipelines/steps/approval/#keeping-the-shared-volume-after-an-approval) the volume when a pipeline is entering approval state +* Whether pipelines in approval state [count or not against concurrency]({{site.baseurl}}/docs/pipelines/steps/approval/#define-concurrency-limits) +* Define the [Service Account]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/#setting-up-ecr-integration---service-account) for Amazon ECR integration. +* Set the default registry where all Public Marketplace Step images are pulled from. Registries listed are from the [Docker Registry]({{site.baseurl}}/docs/integrations/docker-registries/) integration page. + * Example: Public Marketplace Step image is defined to use Docker Hub. If you select a quay.io integration, all Public Marketplace Step images will be pulled from quay.io instead of Docker Hub. + * Note: This does not affect Freestyle Steps. + +Note that the first option affects pipeline resources and/or billing in the case of SaaS pricing. It will also affect users of existing pipelines that depend on this behavior. It is best to enable/disable this option only once at the beginning. + +## Default Behavior for Build Step + +Here you can decide if the build step will push images or not according to your organization’s needs. The options are: + +1. Users need to decide if an image will be pushed or not after it is built +2. All built images are automatically pushed to the default registry +3. All built images are NOT pushed anywhere by default + +Note that this behavior is simply a convenience feature for legacy pipelines. Users can still use a [push step]({{site.baseurl}}/docs/pipelines/steps/push/) in a pipeline and always push an image to a registry regardless of what was chosen in the build step. + +## Related articles +[Creating Pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Git Integration]({{site.baseurl}}/docs/integrations/git-providers/) diff --git a/_docs/pipelines/running-pipelines-locally.md b/_docs/pipelines/running-pipelines-locally.md index f27f166f..3c513987 100644 --- a/_docs/pipelines/running-pipelines-locally.md +++ b/_docs/pipelines/running-pipelines-locally.md @@ -8,7 +8,7 @@ redirect_from: - /docs/troubleshooting/common-issues/access-and-debug-the-pipeline-volume-image/ --- -Codefresh can run your pipelines locally. This is very handy when you need to debug a pipeline, or when you want to do quick changes to the [codefresh.yml file]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) with the fastest turn-around time possible. +Codefresh can run your pipelines locally. This is very handy when you need to debug a pipeline, or when you want to do quick changes to the [codefresh.yml file]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) with the fastest turn-around time possible. ## Prerequisites @@ -60,7 +60,7 @@ codefresh run francisco-codefresh/jan_19/my-basic-pipeline --local -b master -t ### Keeping the pipeline volume in the local workstation If you are familiar with -[how Codefresh pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) you should know about the unique docker volume that is automatically shared between all pipeline steps. +[how Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines) you should know about the unique docker volume that is automatically shared between all pipeline steps. This volume (which also includes the project folder) makes data sharing between all steps very easy (e.g. with thing such as test reports or binary dependencies). @@ -118,9 +118,7 @@ codefresh run francisco-codefresh/jan_19/my-basic-pipeline --local --local-volum When this pipeline runs locally, it will use whatever steps exist in `my-codefresh.yml` instead of the git version. The shared data volume will also be left intact after the build is finished as explained in the previous section. -## What to read next - - -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines) +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Introduction to Codefresh pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines) diff --git a/_docs/pipelines/secrets-store.md b/_docs/pipelines/secrets-store.md index 8162db01..f9fc1101 100644 --- a/_docs/pipelines/secrets-store.md +++ b/_docs/pipelines/secrets-store.md @@ -1,11 +1,11 @@ --- -title: "Using secrets" +title: "Secrets in pipelines" description: "Use Kubernetes secrets in Codefresh" group: configure-ci-cd-pipeline toc: true --- -Once you have [connected Codefresh to your secrets storage]({{site.baseurl}}/docs/integrations/secret-storage/), you can use them in any pipeline or GUI screen. +Once you have [connected Codefresh to your secrets storage]({{site.baseurl}}/docs/integrations/secret-storage/), you can use them in any pipeline or UI screen. > Note: This feature is for Enterprise accounts only. @@ -13,12 +13,13 @@ Once you have [connected Codefresh to your secrets storage]({{site.baseurl}}/doc The syntax for using the secret is {% raw %}`${{secrets.NAME_IN_CODEFRESH.KEY}}`{% endraw %}. -> Note that if you did not include the resource-name as a part of your secret store context creation, the syntax for using your secret differs slightly: -The syntax is: {% raw %}${{secrets.NAME_IN_CODEFRESH.RESOURCE-NAME@KEY}}{% endraw %} The previous KEY portion is now made of two parts separated using @, where the left side is the name of the resource in the namespace, and the right side the key in that resource. +> If you did not include the resource-name as a part of your secret store context creation, the syntax for using your secret differs slightly: + {% raw %}${{secrets.NAME_IN_CODEFRESH.RESOURCE-NAME@KEY}}{% endraw %} + The previous KEY portion is now made of two parts separated using @, where the left side is the name of the resource in the namespace, and the right side the key in that resource. To use the secret in your pipeline, you have two options: -Define it as a pipeline variable: +* Define it as a pipeline variable: {% include image.html @@ -44,7 +45,7 @@ steps: {% endraw %} {% endhighlight %} -Or use it directly in your yaml +* Use the secret directly in your YAML `codefresh.yaml` {% highlight yaml %} @@ -63,11 +64,11 @@ steps: {% endhighlight %} -## Using secrets in the Codefresh GUI +## Using secrets in the Codefresh UI You can also use secrets in the GUI screens that support them. Currently you can use secrets in: -* Values in [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) +* Values in [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) * Integration with [cloud storage]({{site.baseurl}}/docs/testing/test-reports/#connecting-your-storage-account) Where secret integration is supported, click on the lock icon and enable the toggle button. You will get a list of your connected secrets: @@ -87,10 +88,9 @@ If you have already specified the resource field during secret definition the ju If you didn't include a resource name during secret creation then enter the full name in the field like `my-secret-resource@my-secret-key`. -## What to Read Next - -* [Shared Configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) -* [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) -* [Running pipelines locally]({{site.baseurl}}/docs/configure-ci-cd-pipeline/running-pipelines-locally/) -* [Debugging Pipelines]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) +## Related articles +[Shared Configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) +[Git triggers]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) +[Running pipelines locally]({{site.baseurl}}/docs/pipelines/running-pipelines-locally/) +[Debugging Pipelines]({{site.baseurl}}/docs//yaml-examples/examples/trigger-a-k8s-deployment-from-docker-registry/) diff --git a/_docs/pipelines/shared-configuration.md b/_docs/pipelines/shared-configuration.md index 5f47aff6..a738b7d5 100644 --- a/_docs/pipelines/shared-configuration.md +++ b/_docs/pipelines/shared-configuration.md @@ -1,11 +1,11 @@ --- -title: "Shared configuration" +title: "Shared configuration for piplines" description: "How to keep your pipelines DRY" group: configure-ci-cd-pipeline toc: true --- -After creating several pipelines in Codefresh you will start to notice several common values between them. Common examples are access tokens, environment URLs, configuration properties etc. +After creating several pipelines in Codefresh, you will start to notice several common values between them. Common examples are access tokens, environment URLs, configuration properties etc. Codefresh allows you to create those shared values in a central place and then reuse them in your pipelines avoiding the use of copy-paste. @@ -107,7 +107,7 @@ max-width="50%" %} Once you click *Add* the values from the shared configuration will be appended to the ones -you have in your pipelines. In case of similar values the shared configuration will follow the [precedence rules]({{site.baseurl}}/docs/codefresh-yaml/variables/#user-provided-variables). +you have in your pipelines. In case of similar values the shared configuration will follow the [precedence rules]({{site.baseurl}}/docs/pipelines/variables/#user-provided-variables). ## Using shared Helm values @@ -135,7 +135,7 @@ Not only it will be used for this Helm chart, but it will be added in your globa ## Using values from the Shared Configuration in your Helm step -Additionally, you can define shared variables in your account settings and reuse those across your Helm steps, and specifically, in your [custom Helm values](https://codefresh.io/docs/docs/new-helm/using-helm-in-codefresh-pipeline/#helm-values). +Additionally, you can define shared variables in your account settings and reuse those across your Helm steps, and specifically, in your [custom Helm values]({{site.baseurl}}/docs/docs/new-helm/using-helm-in-codefresh-pipeline/#helm-values). Under *Account Setting* > *Shared Configuration*, add the variable to your shared configuration. @@ -257,9 +257,8 @@ See the [context section](https://codefresh-io.github.io/cli/contexts/create-con -## What to read next - -* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +## Related articles +[Variables]({{site.baseurl}}/docs/pipelines/variables/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) diff --git a/_docs/pipelines/variables.md b/_docs/pipelines/variables.md index 371b0443..19f2c8a4 100644 --- a/_docs/pipelines/variables.md +++ b/_docs/pipelines/variables.md @@ -1,5 +1,5 @@ --- -title: "Variables" +title: "Variables in pipelines" description: "" group: codefresh-yaml redirect_from: @@ -75,11 +75,11 @@ feature-vb145dh Notice that this syntax is specific to Codefresh and is **only** available within the Codefresh YAML file itself. If you want to write scripts or programs that use the Codefresh variables, you need to make them aware of the environment variable form. -. + ## System variables -All system provided variables will also be automatically injected to any freestyle step as environment variables. +System variables are automatically injected to any freestyle step as environment variables. > It is important to understand that all Git related variables such `CF_BRANCH`, `CF_COMMIT_MESSAGE`, `CF_REVISION` etc. are coming directly from the Git provider you use and have the same limitations of that provider. For example GitLab is sending less information in pull request events than normal pushes, and Bitbucket sends only the short hash of a commit in pull request events. We suggest you read the documentation of your Git provider first to understand what information is available for every Git event @@ -169,7 +169,7 @@ Variables that are created by steps can have members. The members depend on the -## GitHub Release Variables +## GitHub release variables GitHub allows you to create [releases](https://help.github.com/articles/creating-releases/) for marking specific Git tags for general availability. @@ -185,7 +185,7 @@ You can set a [trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/ | {% raw %}`${{CF_RELEASE_ID}}`{% endraw %} | Internal ID for this release | | {% raw %}`${{CF_PRERELEASE_FLAG}}`{% endraw %} | true if the release if marked as non-production ready, false if it is ready for production | -## GitHub Pull Request Variables +## GitHub Pull Request variables When a pull request is closed in GitHub, the following variables are also available @@ -197,9 +197,9 @@ When a pull request is closed in GitHub, the following variables are also availa | {% raw %}`${{CF_PULL_REQUEST_MERGED_COMMIT_SHA}}`{% endraw %} | the commit SHA on the base branch after the pull request was merged (in most cases it will be master) | | {% raw %}`${{CF_PULL_REQUEST_HEAD_COMMIT_SHA}}`{% endraw %} | the commit SHA on the head branch (the branch that we want to push) | -## User Provided Variables +## User-defined variables -User provided variables can be defined at 6 levels: +User variables can be defined at 6 levels: 1. Manually within a step using the [export](http://linuxcommand.org/lc3_man_pages/exporth.html) command or in any **subsequent** step with the [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#using-cf_export-command) command 1. [Freestyle Step Definition]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/#examples) (using the `environment` field) @@ -328,13 +328,11 @@ max-width="60%" >Notice that this feature is currently available only in Enterprise accounts. -## Escape Characters +## Escape characters When passing special characters through environmental variables `\` can be used as an escape character. For example if you were passing a cassandra connection string you might do something like `Points\=hostname\;Port\=16376\;Username\=user\;Password\=password` This will safely escape `;` and `=`. -## What to read next - -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) -* [Expression Syntax]({{site.baseurl}}/docs/codefresh-yaml/condition-expression-syntax/) +## Related articles +[Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +[Codefresh Conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) diff --git a/_docs/pipelines/what-is-the-codefresh-yaml.md b/_docs/pipelines/what-is-the-codefresh-yaml.md index 36f3344f..51ba8a73 100644 --- a/_docs/pipelines/what-is-the-codefresh-yaml.md +++ b/_docs/pipelines/what-is-the-codefresh-yaml.md @@ -14,7 +14,7 @@ toc: true Codefresh offers its own built-in format for creating pipelines. The pipeline specification is based on the YAML syntax allowing you to describe your pipelines in a completely declarative manner. -Using Codefresh yaml is the recommended way to [create pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/). +Using Codefresh yaml is the recommended way to [create pipelines]({{site.baseurl}}/docs/pipelines/pipelines/). ## Simple example for codefresh.yml @@ -40,9 +40,9 @@ steps: - gulp unit_test {% endhighlight %} -It contains two [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), one named *build_image* that creates a docker image, and another one called *perform_tests* that runs unit test with `gulp`. +It contains two [steps]({{site.baseurl}}/docs/pipelines/steps/), one named *build_image* that creates a docker image, and another one called *perform_tests* that runs unit test with `gulp`. -If you want to know more about how steps work in Codefresh make sure to read [the introduction to Pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) first, before moving on. +If you want to know more about how steps work in Codefresh make sure to read [the introduction to pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) first, before moving on. ## Basic pipeline syntax @@ -63,38 +63,38 @@ steps: [step-contents] {% endhighlight %} -You must define a step type for each step, unless you are using a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). Each step uses Docker images and containers as facilitators for execution. For example, the [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) step spins up a container and executes the specified shell commands from the YAML file. +You must define a step type for each step, unless you are using a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). Each step uses Docker images and containers as facilitators for execution. For example, the **Freestyle** step spins up a container and executes the specified shell commands from the YAML file. The step names should be unique within the same pipeline. This mainly affects the visualization of the pipeline when it runs. -Each step produces a resource, which you can [reference](https://github.com/codefresh-contrib/python-flask-sample-app/blob/master/codefresh.yml#L23) in other steps, and are executed in real-time. For example, a [**Freestyle**]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) step can reference an image that was produced by a [**Build**]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) step. This allows you to chain steps together and create highly-customized builds. +Each step produces a resource, which you can [reference](https://github.com/codefresh-contrib/python-flask-sample-app/blob/master/codefresh.yml#L23) in other steps, and are executed in real-time. For example, a **Freestyle** step can reference an image that was produced by a [**Build**]({{site.baseurl}}/docs/pipelines/steps/build/) step. This allows you to chain steps together and create highly-customized builds. + -
##### Variables -Steps chaining and referencing is possible due to implementation of variables in yml file - read more on relevant [section]({{site.baseurl}}/docs/codefresh-yaml/variables/) -
+Steps chaining and referencing is possible due to implementation of variables in the YAML file - read more on relevant [section]({{site.baseurl}}/docs/pipelines/variables/). + {: .table .table-bordered .table-hover} | Step Type | Description | | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| [Freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) | Executes one or more shell commands in a container similar to `docker run`. | -| [Build]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) | Builds a Docker image like `docker build`. | -| [Push]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) | Pushes a Docker image to an external registry similar to `docker tag` and `docker push`. | -| [Git Clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) | Overrides the default git clone behavior. | -| [Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) | Starts a Docker Composition like `docker-compose`. Discarded once pipelines finishes. | -| [Launch Composition]({{site.baseurl}}/docs/codefresh-yaml/steps/launch-composition/) | Starts a long term Docker composition that stays up after the end of the pipeline. | -| [Deploy]({{site.baseurl}}/docs/codefresh-yaml/steps/deploy/) | Deploys to Kubernetes clusters. | -| [Approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) | Pauses a pipeline and waits for human intervention. | +| [Freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/) | Executes one or more shell commands in a container similar to `docker run`. | +| [Build]({{site.baseurl}}/docs/pipelines/steps/build/) | Builds a Docker image like `docker build`. | +| [Push]({{site.baseurl}}/docs/pipelines/steps/push/) | Pushes a Docker image to an external registry similar to `docker tag` and `docker push`. | +| [Git Clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) | Overrides the default git clone behavior. | +| [Composition]({{site.baseurl}}/docs/pipelines/steps/composition/) | Starts a Docker Composition like `docker-compose`. Discarded once pipelines finishes. | +| [Launch Composition]({{site.baseurl}}/docs/pipelines/steps/launch-composition/) | Starts a long term Docker composition that stays up after the end of the pipeline. | +| [Deploy]({{site.baseurl}}/docs/pipelines/steps/deploy/) | Deploys to Kubernetes clusters. | +| [Approval]({{site.baseurl}}/docs/pipelines/steps/approval/) | Pauses a pipeline and waits for human intervention. | -For more information on creating your own step, see the [steps page]({{site.baseurl}}/docs/codefresh-yaml/steps/). +For more information on creating your own step, see the [Steps in piplines]({{site.baseurl}}/docs/pipelines/steps/). You can also see the [full YAML specification]({{site.baseurl}}/docs/integrations/codefresh-api/#full-pipeline-specification) supported for pipelines. Note however that several fields are only accessible by using the [Codefresh API]({{site.baseurl}}/docs/integrations/codefresh-api) or [CLI](https://codefresh-io.github.io/cli/). ## Yaml validation -If you are editing Codefresh yaml within the Codefresh GUI, the editor will automatically highlight errors as they happen. +If you are editing Codefresh yaml within the Codefresh UI, the editor will automatically highlight errors as they happen. This allows you to make quick edits (and possibly run some builds) straight from the GUI. Once you are happy with your pipeline you should commit it to your repository as `codefresh.yml` (pipeline as code). @@ -126,7 +126,7 @@ By default, Codefresh will execute all steps in the yaml file and instantly fail presents an error. To change this behavior add the `fail_fast:false` property in any step that you wish to be ignored in case of errors. -For example, if you have a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that runs integration tests, and you don't want the whole pipeline +For example, if you have a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) that runs integration tests, and you don't want the whole pipeline to fail if any of the tests fail, add the `fail_fast` line to that step: @@ -144,21 +144,22 @@ Now the pipeline will continue to run even if the step `perform_tests` fails. Notice also that by default Codefresh pipelines run in *sequential mode*. All steps will be executed one after the other and in the same order as included in the `codefresh.yml` file. -If you wish to use parallel steps in your pipelines, see the [parallel steps]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) page. +If you wish to use parallel steps in your pipelines, see the [parallel steps]({{site.baseurl}}/docs/pipelines/advanced-workflows/) page. ## Working directories In the context of a step, a working directory can be of the following type: {: .table .table-bordered .table-hover} -| Working Directory | Description | -| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Empty | Defaults to the [Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) (found at `/codefresh/volume`). If there is a [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) with the special name `main_clone` then the default working directory for built-in steps is now the [project folder]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#cloning-the-source-code) that was checked out - this only applies to [built-in]({{site.baseurl}}/docs/codefresh-yaml/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/codefresh-yaml/steps/#creating-a-typed-codefresh-plugin). | -| Variable that contains the ID of a [Git-Clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step | Runs the step within the cloned directory. | -| Variable that contains the ID of any other step | Runs the step within the same working directory that the specified was executed. This option is not available for for [**Git-Clone**]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) steps. | -| Absolute filesystem path | Treated as is within the container. | -| Relative filesystem path | Treated as relative path from the cloned directory of the service | -| 'IMAGE_WORK_DIR' | Use this value in order to use the image working directory for example:
`working_directory: IMAGE_WORK_DIR` | +| Working Directory | Description | +| --------------------- | -------------------------------------------- | +| Empty | Defaults to the [Codefresh volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) (found at `/codefresh/volume`). If there is a [git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) with the special name `main_clone` then the default working directory for built-in steps is now the [project folder]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#cloning-the-source-code) that was checked out - this only applies to [built-in]({{site.baseurl}}/docs/pipelines/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/pipelines/steps/#creating-a-typed-codefresh-plugin). | +| Variable that contains the ID of a [Git-Clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step | Runs the step within the cloned directory. | +| Variable that contains the ID of any other step | Runs the step within the same working directory that the specified was executed. This option is not available for for [**Git-Clone**]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) steps. | +| Absolute filesystem path | Treated as is within the container. | +| Relative filesystem path | Treated as relative path from the cloned directory of the service | +| 'IMAGE_WORK_DIR' | Use this value in order to use the image working directory for example:
`working_directory: IMAGE_WORK_DIR` | + ## Retrying a step @@ -227,7 +228,7 @@ Notice that Codefresh also provides the following variables that allow you chang * `CF_CURRENT_ATTEMPT` contains the number of current retry attempt. * `CF_MAX_ATTEMPTS` contains all the number of total attempts defined. -The retry mechanism is available for all kinds of [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/). +The retry mechanism is available for all kinds of [steps]({{site.baseurl}}/docs/pipelines/steps/). ## Escaping strings @@ -362,13 +363,12 @@ For the second step, we extend the first one and only change the name of the clu to point to production. Everything else (i.e. namespace and service) are exactly the same. -## What to read next - -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) -* [Advanced workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [YAML examples]({{site.baseurl}}/docs/yaml-examples/examples/) +## Related articles +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) +[Variables]({{site.baseurl}}/docs/pipelines/variables/) +[Advanced workflows]({{site.baseurl}}/docs/pipelines/advanced-workflows/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[YAML examples]({{site.baseurl}}/docs/yaml-examples/examples/) diff --git a/images/pipeline/pipeline-settings/pause-pipeline-enabled.png b/images/pipeline/pipeline-settings/pause-pipeline-enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..8c7c4305aea00f9d43f89a1d3f082218c829568a GIT binary patch literal 23131 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 MGwaiprk>IN0c<>FcmMzZ literal 0 HcmV?d00001 diff --git a/images/pipeline/pipeline-settings/pipeline-settings-ui.png b/images/pipeline/pipeline-settings/pipeline-settings-ui.png new file mode 100644 index 0000000000000000000000000000000000000000..105544c92e4511f70fb46d0d88acfb4adb1756d7 GIT binary patch literal 122724 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 odow*>yX?HQt& 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%0D&<15P`dO@ZD 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 WK~&h~Tla2&F9q304+`%a`TsxPuKMNx literal 0 HcmV?d00001 From 0c19a9cc3aa752d05126a52cd10fa5f526e80cfa Mon Sep 17 00:00:00 2001 From: NimRegev Date: Sun, 4 Dec 2022 10:14:46 +0200 Subject: [PATCH 5/8] Update nav and home yamls Added entries to home and nav yamls for pipeline topics --- _data/home-content.yml | 25 +++++++++ _data/nav.yml | 122 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 134 insertions(+), 13 deletions(-) diff --git a/_data/home-content.yml b/_data/home-content.yml index 18f73ad1..2649fa31 100644 --- a/_data/home-content.yml +++ b/_data/home-content.yml @@ -46,7 +46,32 @@ - title: Add Git Sources to runtimes localurl: /docs/runtime/git-sources/ + - title: Pipelines + icon: images/home-icons/pipeline.svg + url: '' + links: + - title: Introduction to Pipelines + localurl: /docs/pipelines/introduction-to-codefresh-pipelines/ + - title: Creating Pipelines + localurl: /docs/pipelines/pipelines/ + - title: Pipeline triggers + localurl: /docs/pipelines/triggers/ + - title: Monitoring pipelines + localurl: /docs/pipelines/monitoring-pipelines/ + - title: Shared Configuration + localurl: /docs/pipelines/shared-configuration/ + - title: Using secrets + localurl: /docs/pipelines/secrets-store/ + - title: Pipeline caching + localurl: /docs/pipelines/pipeline-caching/ + - title: Running pipelines locally + localurl: /docs/pipelines/running-pipelines-locally/ + - title: Debugging pipelines + localurl: /docs/pipelines/debugging-pipelines/ + + +- title: Workflows icon: images/home-icons/pipeline.svg url: '' links: diff --git a/_data/nav.yml b/_data/nav.yml index dc432643..0ae19a31 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -43,27 +43,121 @@ - title: Installation - url: "/runtime" + url: "/installation" pages: - title: Installation environments url: "/installation-options" - - title: Set up a hosted runtime environment - url: "/hosted-runtime" - - title: Hybrid runtime requirements - url: "/requirements" - - title: Install hybrid runtimes - url: "/installation" - - title: Manage provisioned runtimes + - title: Runner installation + url: "/codefresh-runner" + - title: Hosted GitOps Runtime installation + url: "/hosted-runtime" + - title: Hybrid GitOps Runtime installation + url: "/hybrid-gitops" + - title: On-Premises Installation + url: "/codefresh-on-prem" + - title: On-Premises Upgrade + url: "/codefresh-on-prem-upgrade" + - title: Monitoring & managing GitOps Runtimes url: "/monitor-manage-runtimes" - - title: Monitor provisioned hybrid runtimes - url: "/monitoring-troubleshooting" - - title: Add external clusters to runtimes + - title: Add external clusters to GitOps Runtimes url: "/managed-cluster" - - title: Add Git Sources to runtimes + - title: Add Git Sources to to GitOps Runtimes url: "/git-sources" +- title: Codefresh pipelines + url: "/piplines" + pages: + - title: "Introduction to Codefresh pipelines" + url: "/introduction-to-codefresh-pipelines" + - title: "Creating pipelines" + url: "/pipelines" + - title: "Steps" + url: "/steps" + sub-pages: + - title: "Git-clone" + url: "/git-clone" + - title: "Freestyle" + url: "/freestyle" + - title: "Build" + url: "/build" + - title: "Push" + url: "/push" + - title: "Composition" + url: "/composition" + - title: "Launch-composition" + url: "/launch-composition" + - title: "Deploy" + url: "/deploy" + - title: "Approval" + url: "/approval" + - title: "Triggers" + url: "/triggers" + sub-pages: + - title: "Git Triggers" + url: "/git-triggers" + - title: "DockerHub Triggers" + url: "/dockerhub-triggers" + - title: "Azure Triggers" + url: "/azure-triggers" + - title: "Quay Triggers" + url: "/quay-triggers" + - title: "Helm Triggers" + url: "/helm-triggers" + - title: "Artifactory Triggers" + url: "/jfrog-triggers" + - title: "Timer (Cron) Triggers" + url: "/cron-triggers" + - title: "Variables" + url: "/variables" + - title: "Conditional execution of steps" + url: "/conditional-execution-of-steps" + - title: "Post-step Operations" + url: "/post-step-operations" + - title: "Hooks" + url: "/hooks" + - title: "Annotations" + url: "/annotations" + - title: "Stages" + url: "/stages" + - title: "Caching" + url: "/pipeline-caching" + - title: "Debugging pipelines" + url: "/debugging-pipelines" + - title: "Monitoring pipelines" + url: "/monitoring-pipelines" + - title: "Complex pipelines" + url: "/advanced-workflows" + - title: "Running pipelines locally" + url: "/running-pipelines-locally" + - title: "Configuration" + url: "/configuration" + sub-pages: + - title: "Shared Configuration" + url: "/shared-configuration" + - title: "Using Secrets" + url: "/secrets-store" + - title: "Global settings" + url: "/pipeline-settings" + - title: "Public logs and status badges" + url: "/build-status" + - title: "Service containers" + url: "/service-containers" + - title: "Deployment environments" + url: "/deployment-environments" + - title: "Docker image Metadata" + url: "/docker-image-metadata" + - title: "Pipeline definitions YAML" + url: "/what-is-the-codefresh-yaml" + + + + + + + + -- title: Pipelines +- title: Workflows url: "/pipelines" pages: - title: Creation @@ -202,6 +296,8 @@ - title: Reference url: "/reference" pages: + - title: Runner installation behind firewalls + url: "/behind-the-firewall" - title: Git tokens url: "/git-tokens" - title: Secrets From 4b1c8bb0e64e417816686b93b389c3780a167556 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Sun, 4 Dec 2022 14:37:20 +0200 Subject: [PATCH 6/8] Update pipeline and git triggers Copied set disk space from Classic to pipeline topic and git triggers --- _docs/pipelines/pipelines.md | 24 +++++++++++++++++- _docs/pipelines/triggers/git-triggers.md | 8 ++++++ .../pipeline/create/set-build-disk-space.png | Bin 0 -> 123287 bytes 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 images/pipeline/create/set-build-disk-space.png diff --git a/_docs/pipelines/pipelines.md b/_docs/pipelines/pipelines.md index e2109c9d..911b25fc 100644 --- a/_docs/pipelines/pipelines.md +++ b/_docs/pipelines/pipelines.md @@ -216,7 +216,29 @@ You can define multiple external resources in a single pipeline. - Small (recommended for 1-2 concurrent steps) - Medium (recommended 3-4 steps) - Large (recommended 5-6 steps) - + +#### Set disk space for pipeline builds +Set the disk space you need for the pipeline's build volume. Configuring the disk space per pipeline build volume prevents out-of-space scenarios that lead to failed builds. The disk space set for the pipeline is inherited by all the builds run for the pipeline. + +Codefresh calculates the available range according to the disk size, and automatically sets the disk space for the build volume to 70% of the total disk space. You can either retain the default allocation or change as needed. + +>You can also configure the disk space for a [specific trigger]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/#set-minimum-disk-space-for-build-volume-by-trigger) used by the pipeline or for a specific run, and override what's set for the pipeline. + +1. Select the pipeline for which to set the disk space. +1. Select **Settings**, and then **Runtime**. +1. Enable **Set minimum required disk space** and either retain the default displayed or change as needed. + +{% include +image.html +lightbox="true" +file="/images/pipeline/create/set-build-disk-space.png" +url="/images/pipeline/create/set-build-disk-space.png" +alt="Set disk space for pipeline builds" +caption="Set disk space for pipeline builds" +max-width="60%" +%} + + ## Using Pipeline Templates Codefresh also supports the creation of pipeline "templates", which are blueprints for creating new pipelines. diff --git a/_docs/pipelines/triggers/git-triggers.md b/_docs/pipelines/triggers/git-triggers.md index ce1d37ce..de0a551e 100644 --- a/_docs/pipelines/triggers/git-triggers.md +++ b/_docs/pipelines/triggers/git-triggers.md @@ -257,6 +257,14 @@ max-width="60%" * *Report notification on pipeline execution* - Decide if [Slack notifications]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) will be sent (as well as status updates back to your Git provider) * *Runtime Environment* - choose to use pipeline [settings]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) or override them +### Set minimum disk space for build volume by trigger +Set the disk space you need for the build volume in the context of the selected trigger. Setting the disk space for the trigger overrides that set for the pipeline. + +1. In **Workflow > Triggers**, expand **Advanced Options**. +1. From the Runtime Environment list, select **Override pipeline settings**, and then select the runtime for which to override the pipeline setting. +1. If required, change the resource size. +1. Enable **Set minimum disk space**, and then change as required. + ## Manually adding the trigger to GitHub When creating a Git trigger in codefresh, sometimes the Git Integration does not have the permissions to create a webhook on the designated repository. When this happens, you get the following error: `Failed to add Trigger`. diff --git a/images/pipeline/create/set-build-disk-space.png b/images/pipeline/create/set-build-disk-space.png new file mode 100644 index 0000000000000000000000000000000000000000..374d2cd027fbea0b7ed0d38dff1d365ff168082e GIT binary patch literal 123287 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 Date: Tue, 6 Dec 2022 11:52:01 +0200 Subject: [PATCH 7/8] Update category name Changed bucket name to workflows and updated x-refs and nav files accordingly --- _data/home-content.yml | 12 +++++++----- _data/nav.yml | 16 +++++----------- _docs/workflows/concurrency-limit.md | 6 ++++-- _docs/workflows/configure-artifact-repository.md | 5 ++++- _docs/workflows/create-pipeline.md | 12 ++++++++---- _docs/workflows/docker-operations.md | 8 -------- _docs/workflows/marketplace.md | 13 ------------- _docs/workflows/nested-workflows.md | 2 +- _docs/workflows/sharing-file-system.md | 2 +- _docs/workflows/using-secrets.md | 8 -------- 10 files changed, 30 insertions(+), 54 deletions(-) delete mode 100644 _docs/workflows/docker-operations.md delete mode 100644 _docs/workflows/marketplace.md delete mode 100644 _docs/workflows/using-secrets.md diff --git a/_data/home-content.yml b/_data/home-content.yml index 2649fa31..09ddbe9f 100644 --- a/_data/home-content.yml +++ b/_data/home-content.yml @@ -75,14 +75,16 @@ icon: images/home-icons/pipeline.svg url: '' links: - - title: Creation - localurl: /docs/pipelines/create-pipeline + - title: Creating workflows + localurl: /docs/workflows/create-pipeline + - title: Nested workflows + localurl: /docs/workflows/nested-workflows/ - title: Configure artifact repository - localurl: /docs/pipelines/configure-artifact-repository/ + localurl: /docs/workflows/configure-artifact-repository/ - title: Selectors for concurrency synchronization - localurl: /docs/pipelines/concurrency-limit/ + localurl: /docs/workflows/concurrency-limit/ - title: Sharing file systems - localurl: /docs/pipelines/sharing-file-system/ + localurl: /docs/workflows/sharing-file-system/ - title: Deployment diff --git a/_data/nav.yml b/_data/nav.yml index 0ae19a31..db343273 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -150,26 +150,20 @@ url: "/what-is-the-codefresh-yaml" - - - - - - - - title: Workflows - url: "/pipelines" + url: "/workflows" pages: - - title: Creation + - title: Creating workflows url: "/create-pipeline" + - title: Nested workflows + url: "/nested-workflows" - title: Configure artifact repository url: "/configure-artifact-repository" - title: Selectors for concurrency synchronization url: "/concurrency-limit" - title: Sharing file systems url: "/sharing-file-system" - - title: Nested workflows - url: "/nested-workflows" + - title: Deployment diff --git a/_docs/workflows/concurrency-limit.md b/_docs/workflows/concurrency-limit.md index 780a53a4..405361dd 100644 --- a/_docs/workflows/concurrency-limit.md +++ b/_docs/workflows/concurrency-limit.md @@ -1,13 +1,13 @@ --- title: "Selectors for concurrency synchronization" description: "" -group: pipelines +group: workflows toc: true --- Argo Workflows has a synchronization mechanism to limit parallel execution of specific workflows or templates within workflows, as required. -The mechanism enforces this with either semaphore or mutex synchronization configurations. For detailed information, see [Synchronization](https://argoproj.github.io/argo-workflows/synchronization/). +The mechanism enforces this with either semaphore or mutex synchronization configurations. For detailed information, see [Synchronization](https://argoproj.github.io/argo-workflows/synchronization/){:target="\_blank"}. Codefresh supports an additional level of concurrency synchronization, with _selectors_, for both workflows and templates. @@ -163,4 +163,6 @@ synchronization: - synchronization-wf-8lf9b semaphore: argo/ConfigMap/semaphore-config/workflow?repository=denis-codefresh/argo-workflows&branch=feature ``` +## Related articles +[Creating workflows]({{site.baseurl}}/docs/workflows/create-pipeline) diff --git a/_docs/workflows/configure-artifact-repository.md b/_docs/workflows/configure-artifact-repository.md index 894ec98c..3f4b6057 100644 --- a/_docs/workflows/configure-artifact-repository.md +++ b/_docs/workflows/configure-artifact-repository.md @@ -1,7 +1,7 @@ --- title: "Configure artifact repository" description: "" -group: pipelines +group: workflows toc: true --- @@ -179,3 +179,6 @@ As the final step in configuring the artifact repository, for the `argo-server` 1. Wait for the configuration changes to take effect on the cluster. 1. Check the `argo-server` service account and verify that it is updated with the user-provided `annotation`. 1. Select the `argo-server-<#>` pod or pods and delete them. + +## Related articles +[Creating workflows]({{site.baseurl}}/docs/workflows/create-pipeline) \ No newline at end of file diff --git a/_docs/workflows/create-pipeline.md b/_docs/workflows/create-pipeline.md index 0f11bf6a..60cb8076 100644 --- a/_docs/workflows/create-pipeline.md +++ b/_docs/workflows/create-pipeline.md @@ -1,7 +1,7 @@ --- -title: "Pipeline creation" +title: "Creating workflows" description: "" -group: pipelines +group: workflows toc: true --- @@ -33,7 +33,7 @@ An intuitive selection mechanism enables you to easily select and configure each ### Delivery Pipeline creation flow Here's a high-level overview of the Delivery Pipeline creation flow. -For step-by-step instructions, see [How to: create a Delivery Pipeline]({{site.baseurl}}/docs/pipelines/create-pipeline/#how-to-create-a-delivery-pipeline). +For step-by-step instructions, see [How to: create a Delivery Pipeline]({{site.baseurl}}/docs/workflows/create-pipeline/#how-to-create-a-delivery-pipeline). 1. Define pipeline name and select Workflow Template to execute 1. Define default values for pipeline workflow template arguments @@ -56,7 +56,7 @@ In the Delivery Pipeline wizard, we have our starter Workflow Template to use as -> To share artifacts between steps in workflows, and to view archived logs for completed workflows, you must [configure an artifact repository in Codefresh]({{site.baseurl}}/docs/pipelines/configure-artifact-repository). +> To share artifacts between steps in workflows, and to view archived logs for completed workflows, you must [configure an artifact repository in Codefresh]({{site.baseurl}}/docs/workflows/configure-artifact-repository). @@ -278,3 +278,7 @@ Follow the step-by-step instructions to guide you through Delivery Pipeline wiza Codefresh commits the pipeline to the Git repository, and then syncs it to the cluster. Wait a few seconds for the sync to complete, and verify that the pipeline is displayed in the [Delivery Pipelines](https://g.codefresh.io/2.0/pipelines){:target="\_blank"} page. +## Related articles +[Selectors for concurrency synchronization]({{site.baseurl}}/docs/workflows/concurrency-limit) +[Nested workflows]({{site.baseurl}}/docs/workflows/nested-workflows) +[Configure artifact repository]({{site.baseurl}}/docs/workflows/configure-artifact-repository) diff --git a/_docs/workflows/docker-operations.md b/_docs/workflows/docker-operations.md deleted file mode 100644 index 4678a46d..00000000 --- a/_docs/workflows/docker-operations.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "Using Docker" -description: "" -group: pipelines -toc: true ---- - -Coming soon diff --git a/_docs/workflows/marketplace.md b/_docs/workflows/marketplace.md deleted file mode 100644 index 4295f74e..00000000 --- a/_docs/workflows/marketplace.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "Codefresh marketplace" -description: "" -group: pipelines -toc: true ---- - -The Codefresh Hub for Argo documentation can be found in its [official repository](https://github.com/codefresh-io/argo-hub). - -Codefresh is fully backing this project and will help all developers that want to contribute to succeed. - -You can find documentation about how to contribute to the argo hub in the [official repository contribute section](https://github.com/codefresh-io/argo-hub#How-to-Contribute) - diff --git a/_docs/workflows/nested-workflows.md b/_docs/workflows/nested-workflows.md index 7264b1bf..7539c44d 100644 --- a/_docs/workflows/nested-workflows.md +++ b/_docs/workflows/nested-workflows.md @@ -1,7 +1,7 @@ --- title: "Nested workflows" description: "" -group: pipelines +group: workflows toc: true --- diff --git a/_docs/workflows/sharing-file-system.md b/_docs/workflows/sharing-file-system.md index 12722a43..c01e0125 100644 --- a/_docs/workflows/sharing-file-system.md +++ b/_docs/workflows/sharing-file-system.md @@ -1,7 +1,7 @@ --- title: "Sharing file systems" description: "" -group: pipelines +group: workflows toc: true --- diff --git a/_docs/workflows/using-secrets.md b/_docs/workflows/using-secrets.md deleted file mode 100644 index 58204057..00000000 --- a/_docs/workflows/using-secrets.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "Using secrets" -description: "" -group: pipelines -toc: true ---- - -Coming soon From 44a95cdf4defe16e2aff7a170387c64b5a00846b Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 19 Dec 2022 08:27:50 +0200 Subject: [PATCH 8/8] Update pipeline topics Added missing images and replaced sidebar with new design --- _data/home-content.yml | 45 --- _data/nav.yml | 303 +++--------------- .../introduction-to-codefresh-pipelines.md | 65 ++-- _docs/pipelines/pipelines.md | 43 +-- .../pipelines/triggers/dockerhub-triggers.md | 6 +- images/pipeline/badges/view-public-logs.png | Bin 115347 -> 132766 bytes .../create/add-pipeline-to-project.png | Bin 0 -> 36802 bytes .../pipeline/create/create-template-menu.png | Bin 0 -> 21069 bytes images/pipeline/create/custom-yml.png | Bin 0 -> 48026 bytes images/pipeline/create/editor.png | Bin 0 -> 32244 bytes images/pipeline/create/external-resources.png | Bin 0 -> 23714 bytes images/pipeline/create/inline-editor.png | Bin 0 -> 80488 bytes .../create/pipeline-from-internal-repo.png | Bin 0 -> 80034 bytes .../create/pipelines-from-repository.png | Bin 0 -> 28746 bytes .../create/pipelines-no-repository.png | Bin 0 -> 32743 bytes images/pipeline/create/predefined-steps.png | Bin 0 -> 17642 bytes 16 files changed, 98 insertions(+), 364 deletions(-) create mode 100644 images/pipeline/create/add-pipeline-to-project.png create mode 100644 images/pipeline/create/create-template-menu.png create mode 100644 images/pipeline/create/custom-yml.png create mode 100644 images/pipeline/create/editor.png create mode 100644 images/pipeline/create/external-resources.png create mode 100644 images/pipeline/create/inline-editor.png create mode 100644 images/pipeline/create/pipeline-from-internal-repo.png create mode 100644 images/pipeline/create/pipelines-from-repository.png create mode 100644 images/pipeline/create/pipelines-no-repository.png create mode 100644 images/pipeline/create/predefined-steps.png diff --git a/_data/home-content.yml b/_data/home-content.yml index 09ddbe9f..6969c3e0 100644 --- a/_data/home-content.yml +++ b/_data/home-content.yml @@ -1,50 +1,5 @@ -- title: Getting Started - icon: images/home-icons/started.svg - url: '' - links: - - title: Introducing Codefresh - localurl: /docs/getting-started/csdp-introduction/ - - title: Quick start - localurl: /docs/getting-started/quick-start/ - - title: Concepts - localurl: /docs/getting-started/main-concepts/ - - title: Entity model - localurl: /docs/getting-started/entity-model/ - - title: Architecture - localurl: /docs/getting-started/architecture/ - - title: GitOps approach - localurl: /docs/getting-started/gitops/ - - title: Frequently asked questions - localurl: /docs/getting-started/faq/ - -- title: Clients - icon: images/home-icons/client.svg - url: '' - links: - - title: Codefresh CLI - localurl: /docs/clients/csdp-cli/ -- title: Installation - icon: images/home-icons/runtimes.svg - url: '' - links: - - title: Installation environments - localurl: /docs/runtime/installation-options/ - - title: Set up a hosted runtime environment - localurl: /docs/runtime/hosted-runtime/ - - title: Hybrid runtime requirements - localurl: /docs/runtime/requirements/ - - title: Install hybrid runtimes - localurl: /docs/runtime/installation - - title: Manage provisioned runtimes - localurl: /docs/runtime/monitor-manage-runtimes/ - - title: Monitor provisioned hybrid runtimes - localurl: /docs/runtime/monitoring-troubleshooting/ - - title: Add external clusters to runtimes - localurl: /docs/runtime/managed-cluster/ - - title: Add Git Sources to runtimes - localurl: /docs/runtime/git-sources/ - title: Pipelines diff --git a/_data/nav.yml b/_data/nav.yml index db343273..db2e488c 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -1,152 +1,88 @@ -- title: Getting started - url: "/getting-started" - pages: - - title: Introducing Codefresh - url: "/csdp-introduction" - - title: Quick start - url: "/quick-start" - sub-pages: - - title: Provision a hosted runtime - url: "/install-hosted" - - title: Prepare for hybrid runtime installation - url: "/verify-requirements" - - title: Install a hybrid runtime - url: "/runtime" - - title: Create an application - url: "/create-app-ui" - - title: Create and commit resources for application - url: "/create-app-specs" - - title: Update the image tag for application - url: "/create-rollout" - - title: Trigger the Hello World example pipeline - url: "/hello-world" - - title: Create a basic CI delivery pipeline - url: "/create-ci-pipeline" - - - - title: Main concepts - url: "/main-concepts" - - title: Entity model - url: "/entity-model" - - title: Architecture - url: "/architecture" - - title: GitOps approach - url: "/gitops" - - title: Frequently asked questions - url: "/faq" - -- title: Clients - url: "/clients" - pages: - - title: Download CLI - url: "/csdp-cli" -- title: Installation - url: "/installation" +- title: CI pipelines + url: "/pipelines" pages: - - title: Installation environments - url: "/installation-options" - - title: Runner installation - url: "/codefresh-runner" - - title: Hosted GitOps Runtime installation - url: "/hosted-runtime" - - title: Hybrid GitOps Runtime installation - url: "/hybrid-gitops" - - title: On-Premises Installation - url: "/codefresh-on-prem" - - title: On-Premises Upgrade - url: "/codefresh-on-prem-upgrade" - - title: Monitoring & managing GitOps Runtimes - url: "/monitor-manage-runtimes" - - title: Add external clusters to GitOps Runtimes - url: "/managed-cluster" - - title: Add Git Sources to to GitOps Runtimes - url: "/git-sources" - -- title: Codefresh pipelines - url: "/piplines" - pages: - - title: "Introduction to Codefresh pipelines" + - title: Introduction to CI pipelines url: "/introduction-to-codefresh-pipelines" - - title: "Creating pipelines" + - title: Creating a CI pipeline url: "/pipelines" - - title: "Steps" + - title: Steps in CI pipelines url: "/steps" sub-pages: - - title: "Git-clone" + - title: Git-clone url: "/git-clone" - - title: "Freestyle" + - title: Freestyle url: "/freestyle" - - title: "Build" + - title: Build url: "/build" - - title: "Push" + - title: Push url: "/push" - - title: "Composition" + - title: Composition url: "/composition" - - title: "Launch-composition" + - title: Launch-composition url: "/launch-composition" - - title: "Deploy" + - title: Deploy url: "/deploy" - - title: "Approval" + - title: Approval url: "/approval" - - title: "Triggers" + - title: Triggers in CI pipelines url: "/triggers" sub-pages: - - title: "Git Triggers" + - title: Git triggers url: "/git-triggers" - - title: "DockerHub Triggers" + - title: DockerHub triggers url: "/dockerhub-triggers" - - title: "Azure Triggers" + - title: Azure triggers url: "/azure-triggers" - - title: "Quay Triggers" + - title: Quay triggers url: "/quay-triggers" - - title: "Helm Triggers" + - title: Helm triggers url: "/helm-triggers" - - title: "Artifactory Triggers" + - title: Artifactory triggers url: "/jfrog-triggers" - - title: "Timer (Cron) Triggers" + - title: Timer (Cron) triggers url: "/cron-triggers" - - title: "Variables" - url: "/variables" - - title: "Conditional execution of steps" + - title: Conditional execution of steps url: "/conditional-execution-of-steps" - - title: "Post-step Operations" + - title: Post-step operations" url: "/post-step-operations" - - title: "Hooks" + - title: Variables in CI pipelines + url: "/variables" + - title: Hooks in CI pipelines url: "/hooks" - - title: "Annotations" + - title: Annotations in CI pipelines url: "/annotations" - - title: "Stages" + - title: Grouping steps into stages url: "/stages" - - title: "Caching" + - title: Caching for CI pipelines url: "/pipeline-caching" - - title: "Debugging pipelines" + - title: Debugging CI pipelines url: "/debugging-pipelines" - - title: "Monitoring pipelines" + - title: Monitoring CI pipelines url: "/monitoring-pipelines" - - title: "Complex pipelines" + - title: Complex CI pipelines url: "/advanced-workflows" - - title: "Running pipelines locally" + - title: Running CI pipelines locally url: "/running-pipelines-locally" - - title: "Configuration" + - title: Configuration for CI pipelines url: "/configuration" sub-pages: - - title: "Shared Configuration" + - title: Shared configuration url: "/shared-configuration" - - title: "Using Secrets" + - title: Secrets for CI pipelines url: "/secrets-store" - - title: "Global settings" + - title: Global CI pipeline settings url: "/pipeline-settings" - - title: "Public logs and status badges" + - title: Public logs and status badges url: "/build-status" - - title: "Service containers" + - title: Service containers url: "/service-containers" - - title: "Deployment environments" + - title: Deployment environments url: "/deployment-environments" - - title: "Docker image Metadata" + - title: Docker image metadata url: "/docker-image-metadata" - - title: "Pipeline definitions YAML" + - title: Pipeline definitions YAML url: "/what-is-the-codefresh-yaml" @@ -164,160 +100,5 @@ - title: Sharing file systems url: "/sharing-file-system" - - -- title: Deployment - url: "/deployment" - pages: - - title: Creating applications - url: "/create-application" - - title: Monitoring applications - url: "/applications-dashboard" - - title: Managing applications - url: "/manage-application" - - title: Images in Codefresh - url: "/images" - - title: Install Argo Rollouts - url: "/install-argo-rollouts" - -- title: Reports & Insights - url: "/reporting" - pages: - - title: Home dashboard - url: "/home-dashboard" - - title: DORA metrics - url: "/dora-metrics" - - -- title: Image enrichment - url: "/integrations" - pages: - - title: Image enrichment with integrations - url: "/image-enrichment-overview" - - title: CI integrations - url: "/ci-integrations" - sub-pages: - - title: Codefresh Classic - url: "/codefresh-classic" - - title: GitHub Actions - url: "/github-actions" - - title: Jenkins - url: "/jenkins" - - title: Issue tracking - url: "/issue-tracking" - sub-pages: - - title: Jira - url: "/jira" - - title: Container registries - url: "/container-registries" - sub-pages: - - title: Amazon ECR - url: "/amazon-ecr" - - title: Docker Hub Registry - url: "/dockerhub" - - title: GitHub Container Registry - url: "/github-cr" - - title: JFrog Artifactory - url: "/jfrog" - - title: Quay Registry - url: "/quay" - -- title: Administration - url: "/administration" - pages: - - title: Account and user management - sub-pages: - - title: Adding a Codefresh account - url: "/create-codefresh-account" - - title: Adding users to accounts - url: "/add-users" - - title: Configure access Control - url: "/access-control" - - title: Setting up OAuth2 authentication for Git providers - url: "/oauth-setup" - - title: Authorize access to organizations/projects - url: "/hosted-authorize-orgs" - - title: Audit in Codefresh - url: "/audit" - - title: Codefresh IP addresses - url: "/platform-ip-addresses" - - title: User self-management - sub-pages: - - title: User settings - url: "/user-settings" - - title: Configuring Git authentication - url: "/manage-pats" - -- title: Single Sign-On - url: /single-sign-on - pages: - - title: Common configuration - url: /team-sync - - title: OpenID Connect - url: /oidc - sub-pages: - - title: Auth0 - url: /oidc-auth0 - - title: Azure - url: /oidc-azure - - title: Google - url: /oidc-google - - title: Okta - url: /oidc-okta - - title: OneLogin - url: /oidc-onelogin - - title: SAML - url: /saml - sub-pages: - - title: JumpCloud - url: /saml-jumpcloud - - title: Okta - url: /saml-okta - - title: OneLogin - url: /saml-onelogin - - title: PingID SSO - url: /saml-pingid - - title: LDAP - url: /ldap - - - - - - -- title: Reference - url: "/reference" - pages: - - title: Runner installation behind firewalls - url: "/behind-the-firewall" - - title: Git tokens - url: "/git-tokens" - - title: Secrets - url: "/secrets" - - title: Shared configuration repo - url: "/shared-configuration" - -- title: What's New? - url: "/whats-new" - pages: - - title: What's new in Codefresh? - url: "/whats-new" - -- title: Troubleshooting - url: "/troubleshooting" - pages: - - title: Runtimes - url: "/runtime-issues" - - -- title: Terms and Privacy Policy - url: "/terms-and-privacy-policy" - pages: - - title: Terms of Service - url: "/terms-of-service" - - title: Privacy Policy - url: "/privacy-policy" - - title: Service Commitment - url: "/sla" diff --git a/_docs/pipelines/introduction-to-codefresh-pipelines.md b/_docs/pipelines/introduction-to-codefresh-pipelines.md index ce33a186..c8d26498 100644 --- a/_docs/pipelines/introduction-to-codefresh-pipelines.md +++ b/_docs/pipelines/introduction-to-codefresh-pipelines.md @@ -11,7 +11,7 @@ toc: true The central component of the Codefresh platform for continuous integration (CI) are pipelines. Pipelines are workflows that contain individual steps, with each step responsible for a specific action in the CI process. -Pipelines can be used to: +Use CI pipelines to: * Compile and package code * Build Docker images @@ -25,20 +25,20 @@ image.html lightbox="true" file="/images/codefresh-yaml/stages/complex-pipeline.png" url="/images/codefresh-yaml/stages/complex-pipeline.png" -alt="Codefresh pipelines" -caption="Codefresh pipelines" +alt="Codefresh CI pipelines" +caption="Codefresh CI pipelines" max-width="90%" %} -## Why are Codefresh pipelines different? +## Why are Codefresh CI pipelines different? -Codefresh offers unique characteristics in pipelines that serve as the cornerstone of the build/deploy process: +Codefresh offers unique characteristics in CI pipelines that serve as the cornerstone of the build/deploy process: -1. All [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) in Codefresh pipelines are executed inside a Docker container of your choosing. +1. All [steps]({{site.baseurl}}/docs/pipelines/steps/) in Codefresh pipelines are executed inside a Docker container of your choosing. 1. All steps in Codefresh share the same "workspace" in the form of a shared Docker volume. 1. The shared Docker volume is automatically cached between pipeline executions. -1. Each successful pipeline automatically pushes its Docker image to the default Docker registry defined in your account. -1. Codefresh has a distributed Docker cache for all build nodes and caches layers similar to the docker daemon on your workstation. This is fully automated, and no configuration is needed in order to activate it. +1. Every successful pipeline automatically pushes its Docker image to the default Docker registry defined in your account. +1. Codefresh has a distributed Docker cache for all build nodes and caches layers similar to the docker daemon on your workstation. This is fully automated, and does not need to be configured to activate it. ### Using Docker containers as build tooling @@ -50,11 +50,11 @@ It is important that you understand how to take advantage of Docker-based pipeli traditional VM solutions. The capability to define your own tooling cannot be understated. It is the fastest way to take full control of your build tools and to upgrade them easily. -With traditional VM-based build solutions you are constrained on the build and deployment tools provided by the vendor. +With traditional VM-based build solutions, you are constrained on the build and deployment tools provided by the vendor. If for example you need a new version of Node/Java/Python other than the one that is provided on the build slave, you have to wait for your vendor to add it. If you need to use a special tool (e.g terraform, gcloud) and the vendor does not support it you are out of luck. -With Codefresh you don't care about what is installed in the runners that execute your builds. They can run *any* Docker image of your choosing. You are free to update the version of the image used at any given time. +With Codefresh you don't have to care about what is installed in the Runners that execute your builds. They can run *any* Docker image of your choosing. You are free to update the version of the image used at any given time. Here is an example: @@ -99,7 +99,7 @@ or your own) to use a build context in your step. This makes Codefresh a future- that exist now and all of them that will appear in the future. As long as there is a Docker image for a tool, Codefresh can use it in a pipeline without any extra configuration. -Codefresh also offers a [marketplace](https://codefresh.io/steps/) with several existing plugins. +Codefresh also offers a [marketplace](https://codefresh.io/steps/){:target="\_blank"} with several existing plugins. {% include image.html @@ -118,10 +118,10 @@ All plugins in the marketplace are open-source, and we accept external contribut ### Sharing the workspace between build steps We have seen in the previous section that Codefresh can use Docker images as the context of a build step. The second -important point to understand regarding Codefresh pipelines is that the default workspace of each step is shared between all steps in a pipeline. +important point to understand regarding Codefresh CI pipelines is that the default workspace of each step is shared between all steps in a pipeline. This happens via a Docker volume which is attached to all Docker containers that represent each step. This volume is -always available at `/codefresh/volume` and is used as the parent folder where the project is cloned. +always available at `/codefresh/volume`, and is used as the parent folder where the project is cloned. {% include image.html @@ -133,10 +133,10 @@ caption="All steps share the same volume" max-width="90%" %} -Anything that is placed on this volume will be available to all steps of the pipeline (as well as to subsequent executions of the same pipeline as we will see later). +Anything in this volume is available to all steps of the pipeline (as well as to subsequent executions of the same pipeline as we will see later). Again, this places Codefresh ahead of traditional solutions that execute build steps in a completely isolated manner. -In traditional VM-based builds, using artifacts produced from one step to another, is a complicated process as one +In traditional VM-based builds, using artifacts produced from one step in another step, is a complicated process as one must declare which artifact folders should be re-used. Artifact re-use sometimes happens with compression/decompression of the respective folder resulting in really slow builds if a project is very big. @@ -176,11 +176,9 @@ max-width="90%" The common volume shared among build steps makes it very easy to create pipelines that work in a gradual manner where any step in the pipeline is using artifacts produced by a previous one. ->The shared volume is **NOT available** in [build steps]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080). There is no folder `/codefresh/volume` inside a Dockerfile for you to access. +>The shared volume is **NOT available** in [build steps]({{site.baseurl}}/docs/pipelines/steps/build/). This is not a Codefresh limitation. Docker itself [does not allow volumes during builds](https://github.com/moby/moby/issues/14080){:target="\_blank"}. There is no folder `/codefresh/volume` inside a Dockerfile for you to access. -You can also use [environment variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) to share information between steps. All predefined environment variables -are available to all steps, and each individual step can use `cf_export` to inject dynamically during the build process -extra environment variables. +You can also use [environment variables]({{site.baseurl}}/docs/pipelines/variables/) to share information between steps. All predefined environment variables are available to all steps, and each individual step can use `cf_export` to dynamically inject extra environment variables during the build process. ## Working with Codefresh pipelines @@ -190,7 +188,7 @@ Now that we know the basics, we can see how you can take advantage of Docker-bas ### Cloning the source code -You can clone source code using the built-in [git-clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) as the first step in a Pipeline, or run manually your own git clone commands in a freestyle step. Codefresh has built-in [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) with all popular git providers (both cloud and on-premises installations). +You can clone source code using the built-in [Git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) as the first step in a CI pipeline, or manually run your own Git clone commands in a freestyle step. Codefresh has built-in [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) with all popular git providers (both cloud and on-premises installations). Codefresh uses the shared volume as the parent folder of the project. So if your pipeline is connected to a Git repo that contains `my-project` the following will happen: @@ -210,7 +208,7 @@ max-width="80%" There are three important points to consider regarding these folders: -1. The [working directory]({{ site.baseurl }}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#working-directories) of each step is by default the project folder (e.g. `/codefresh/volume/my-project`). Therefore +1. The [working directory]({{ site.baseurl }}/docs/pipelines/what-is-the-codefresh-yaml/#working-directories) of each step is by default the project folder (e.g. `/codefresh/volume/my-project`). Therefore your build step can run commands exactly as you would run them locally (e.g. `npm install, pip install, mvn package, bundle install`). 1. Notice that the project folder is placed on the Codefresh volume, so by default it is also available to all other steps. The code that you check out in the beginning, as well as all other files that are created on it, are available to all steps. Once you create `node_modules`, or any other folder that exists inside the project folder, it will automatically persist for all other steps. @@ -218,7 +216,7 @@ your build step can run commands exactly as you would run them locally (e.g. `np 1. Finally, `/codefresh/volume` is an internal folder name, and you should use `{% raw %}${{CF_VOLUME_PATH}}{% endraw %}` in your codefresh.yml file if you really want to reference this folder. You can also reference your project folder as `{% raw %}${{CF_VOLUME_PATH}}/${{CF_REPO_NAME}}{% endraw %}` if you need it. -See the [System Provided Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/#system-provided-variables) section for more information. +See the [System Provided Variables]({{site.baseurl}}/docs/pipelines/variables/#system-provided-variables) section for more information. ### Working with Docker inside a Codefresh pipeline @@ -235,10 +233,10 @@ Usually you want to run a docker command for four reasons: For all these situations Codefresh gives you special pipeline steps that perform the respective action. These are: -1. The [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) -1. The [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) -1. The [compositions step]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) -1. The [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +1. The [build step]({{site.baseurl}}/docs/pipelines/steps/build/) +1. The [push step]({{site.baseurl}}/docs/pipelines/steps/push/) +1. The [compositions step]({{site.baseurl}}/docs/pipelines/steps/composition/) +1. The [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) The commands you define in a freestyle step run automatically in a Docker container that is attached to that step once the pipeline executes. @@ -274,7 +272,7 @@ Each plugin also defines its input/output in the form of environment variables a ### Creating Docker images dynamically as build tools -Now we reach one of the most powerful features of Codefresh pipelines. We have already seen that [freestyle pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) are just a series of commands that run inside the context of a Docker container. In most cases the images used +Now we reach one of the most powerful features of Codefresh pipelines. We have already seen that [freestyle pipeline steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/) are just a series of commands that run inside the context of a Docker container. In most cases the images used for the freestyle steps are known in advance and come from public (e.g. Dockerhub) or [private Docker registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). Codefresh is one the few CI/CD solutions that not only offers easy Docker registry integration @@ -313,8 +311,8 @@ Codefresh employs several caching mechanisms for both Dockerized and non-dockeri ### Calling other pipelines -It is also possible to chain multiple Pipelines together in Codefresh. To accomplish this, Codefresh offers -a special Docker image that contains the [Codefresh CLI](https://codefresh-io.github.io/cli/) and allows you to trigger another pipeline using its name. +It is also possible to chain multiple pipelines together in Codefresh. To accomplish this, Codefresh offers +a special Docker image that contains the [Codefresh CLI](https://codefresh-io.github.io/cli/){:target="\_blank"} and allows you to trigger another pipeline using its name. {% include image.html @@ -326,14 +324,13 @@ caption="Calling another pipeline" max-width="80%" %} -Notice that each Pipeline in Codefresh is completely isolated from the other. They use a different Docker volume so the build context of each one cannot access files from the other. This may change in the future, but for the time being +Notice that each pipeline in Codefresh is completely isolated from the other. They use a different Docker volume so the build context of each one cannot access files from the other. This may change in the future, but for the time being you should know that only steps within the same pipeline can share artifacts. ## Related articles -[Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -[Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -[Build and Docker caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Build and Docker caching]({{site.baseurl}}/docs/pipelines/pipeline-caching/) diff --git a/_docs/pipelines/pipelines.md b/_docs/pipelines/pipelines.md index 911b25fc..b7b41c0c 100644 --- a/_docs/pipelines/pipelines.md +++ b/_docs/pipelines/pipelines.md @@ -20,7 +20,7 @@ Before creating a pipeline, make sure you are familiar with the theory behind [C The aim of Codefresh pipelines is to have re-usable sequences of steps that can be used for different applications (or micro-services) via the use of Git triggers. -All the main concepts are shown below: +The main concepts are shown below: {% include image.html @@ -32,13 +32,14 @@ caption="Pipeline concepts" max-width="60%" %} -* **Projects**: The top-level concept in Codefresh. Projects are used to group related pipelines. In most cases a single project will be a single application (that itself contains many micro-services). You are free to use projects as you see fit. For example, you could create a project for a specific Kubernetes cluster or a specific team/department. +* **Projects**: The top-level concept in Codefresh CI/CD. Projects are used to group related CI pipelines. In most cases, a single project will be a single application that itself contains many microservices. You are free to use projects as you see fit. For example, you could create a project for a specific Kubernetes cluster or for a specific team/department. * **Pipelines**: Each project can have multiple pipelines. Pipelines that belong to a single project can be managed as a unit. You can also create a new pipeline by copying an existing pipeline. Notice that unlike other CI solutions, a pipeline in Codefresh is **NOT** tied to a specific Git repository. You should try to make your pipelines generic enough so that they can be reused for similar applications even when they exist in different Git repositories (a fairly typical setup for microservices). -* **Pipeline steps**: Each pipeline has a definition that defines the [pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) that are executed each time this pipeline is triggered. The definition of a pipeline is described in a special [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file. The `codefresh.yml` file can be fetched from the same repository as that of the source code, from a completely different repository, or even defined in-place in the Codefresh pipeline editor. Again, notice you can have a pipeline that checks out its source code from Git repository A, but actually defines its steps in a `codefresh.yml` file that is fetched from Git repository B. +* **Pipeline steps**: Each pipeline has a definition that defines the [pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) that are executed each time the pipeline is triggered. The definition of a pipeline is described in a special [codefresh.yml]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) file. The `codefresh.yml` file can be fetched from the same repository as that of the source code, from a completely different repository, or even defined in-place in the Codefresh pipeline editor. Again, notice you can have a pipeline that checks out its source code from Git repository A, but actually defines its steps in a `codefresh.yml` file that is fetched from Git repository B. -* **Triggers**: A pipeline can have zero, one, or more [triggers]({{site.baseurl}}/docs/pipeline/triggers/). Codefresh supports several kinds of triggers such as Git, Cron, and Docker push triggers. Triggers that happen with Git webhooks can come from the same Git repository that contains the git code, **OR**, a completely different repository. Triggers are the linking medium between a pipeline and a Git repository. You can have a pipeline with multiple triggers to be executed when a code change happens to any of them. +* **Triggers**: A pipeline can have zero, one, or many [triggers]({{site.baseurl}}/docs/pipelines/triggers/). Triggers are the linking medium between a pipeline and a Git repository. Codefresh supports several kinds of triggers such as Git, Cron, and Docker push triggers. +Triggers that happen with Git webhooks can come from the same Git repository that contains the git code, **OR**, a completely different repository. You can have a pipeline with multiple triggers to be executed when a code change happens to any of them. With these basic building blocks, you can define many complex workflows. In particular, it is very easy in Codefresh to create a scenario where: @@ -46,7 +47,7 @@ With these basic building blocks, you can define many complex workflows. In part 1. The pipeline reads its `codefresh.yml` file from Git repository B 1. The pipeline clones source code from Git repository C (and starts packaging/compiling it) -Of course, it also possible to have a simpler scenario where the trigger, the pipeline steps and the source code of the application are all defined for the same GIT repository. +Of course, you can also have a simpler scenario where the trigger, the pipeline steps and the source code of the application are all defined for the same Git repository. ## Creating a pipeline @@ -75,14 +76,14 @@ or by copying an existing one from the same project or a completely different pr 1. The main window shows the definition of the current pipeline. The screenshot shows the inline editor but pipelines can also be defined from external files (checked into source control) as explained later. -1. The right part of the window shows extra settings for this pipeline such as [premade steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), [triggers]({{site.baseurl}}/docs/pipelines/triggers/) and launch variables/parameters. +1. The right part of the window shows extra settings for this pipeline such as [predefined steps]({{site.baseurl}}/docs/codefresh-yaml/steps/), [triggers]({{site.baseurl}}/docs/pipelines/triggers/) and launch variables/parameters. -### Using the Inline Pipeline Editor +### Using the Inline pipeline editor -When first creating a pipeline you will see an inline editor that allows you to define the [pipeline yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) right there in the Codefresh UI. This is great when you are starting a new project because it offers you really quick feedback. You can edit the yml steps, run a build, edit again, run a build and so on. +When first creating a pipeline you will see an inline editor that allows you to define the [pipeline yml]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) right there in the Codefresh UI. This is great when you are starting a new project because it offers you really quick feedback. You can edit the yml steps, run a build, edit again, run a build and so on. {% include @@ -106,12 +107,12 @@ On the top right of the panel you have additional controls: Notice that in the editor you can expand/collapse individual yaml blocks using the arrow triangles on the left of each blocks. The initial pipeline presented in the editor is suggested by Codefresh according to the contents of your Git repository. -> You can also see the suggested Codefresh pipeline for any public git repository by using the [analyze option](https://codefresh-io.github.io/cli/analyzer/) of the Codefresh CLI. +> You can also see the suggested Codefresh pipeline for any public git repository by using the [analyze option](https://codefresh-io.github.io/cli/analyzer/){:target="\_blank"} of the Codefresh CLI. ## Loading codefresh.yml from Version Control -Working with the inline editor is very convenient in the beginning, but it makes your pipeline definition only exist within the Codefresh UI and therefore goes against the basic principles of [infrastructure as code](https://en.wikipedia.org/wiki/Infrastructure_as_Code). Once you are happy with how your pipeline works you should commit it to a Git repository (which can be the same one that has the source code of the application or a completely different one). +Working with the inline editor is very convenient in the beginning, but it makes your pipeline definition only exist within the Codefresh UI and therefore goes against the basic principles of [infrastructure as code](https://en.wikipedia.org/wiki/Infrastructure_as_Code){:target="\_blank"}. Once you are happy with how your pipeline works you should commit it to a Git repository (which can be the same one that has the source code of the application or a completely different one). You can click on the *Inline YAML* header and switch it to *Use YAML from URL* or *Use YAML from Repository*. @@ -135,8 +136,8 @@ Once you create your pipeline you can also click on the top tab called *Settings ### General -- **Pipeline Name**: The name of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) -- **Pipeline ID**: The ID of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/)) +- **Pipeline Name**: The name of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/){:target="\_blank"}) +- **Pipeline ID**: The ID of your pipeline (useful for working with the [Codefresh CLI](https://codefresh-io.github.io/cli/){:target="\_blank"}) > When working with the Codefresh CLI, the Pipeline Name and ID are interchangeable. - **Pipeline Description**: Freetext pdescription of the pipeline. - **Pipeline Tags**: One or more tags used for [access control]({{site.baseurl}}/docs/administration/access-control/) @@ -155,18 +156,18 @@ Once you create your pipeline you can also click on the top tab called *Settings - Once a build is created terminate previous builds only from a specific branch (name matches a regular expression) - Once a build is created, terminate all other running builds - Once a build is terminated, terminate all child builds initiated from it -- **Pending approval volume**: Choose what happens with the [pipeline volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) when a pipeline is waiting for [approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) +- **Pending approval volume**: Choose what happens with the [pipeline volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) when a pipeline is waiting for [approval]({{site.baseurl}}/docs/pipelines/steps/approval/#keeping-the-shared-volume-after-an-approval) - Keep the volume available - Discard the volume - Honor the option defined globally in your Codefresh account -- **Pending approval concurrency limit effect**: Determines if a build that is pending approval [counts against]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#define-concurrency-limits) the concurrency limits or not +- **Pending approval concurrency limit effect**: Determines if a build that is pending approval [counts against]({{site.baseurl}}/docs/pipelines/steps/approval/#define-concurrency-limits) the concurrency limits or not - Builds in pending approval will **not** be counted when determining the concurrency limit for a pipeline - Builds in pending approval will **be** counted when determining the concurrency limit for a pipeline - Honor the option defined globally in your Codefresh account The **Pipeline and Trigger Concurrency** limits are very important as they allow you to define how many instances of a pipeline can run in parallel when multiple commits or multiple pull requests take place. -> Notice that these limits are *unrelated* to [parallelism within a single pipeline]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/). +> Notice that these limits are *unrelated* to [parallelism within a single pipeline]({{site.baseurl}}/docs/pipelines/advanced-workflows/). Some common scenarios are: @@ -182,7 +183,7 @@ Some common scenarios are: * You are interested only on the latest commit of a branch. If pipelines from earlier commits are still running you want to terminate them. * You don't want to wait for children pipelines to finish (i.e. when a pipeline calls another pipeline) or when a new build starts for a parent pipeline. -For the volume behavior during approvals, notice that if [you keep the volume available]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/#keeping-the-shared-volume-after-an-approval) on the pipeline while it is waiting for approval it will still count as "running" against your pricing tier limit. +For the volume behavior during approvals, notice that if [you keep the volume available]({{site.baseurl}}/docs/pipelines/steps/approval/#keeping-the-shared-volume-after-an-approval) on the pipeline while it is waiting for approval it will still count as "running" against your pricing tier limit. ### External resources @@ -242,7 +243,7 @@ max-width="60%" ## Using Pipeline Templates Codefresh also supports the creation of pipeline "templates", which are blueprints for creating new pipelines. -To enable the creation of pipelines from templates first visit the global pipeline configuration at [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings) and toggle the *Enable Pipeline Templates* button. +To enable the creation of pipelines from templates first visit the global pipeline configuration at [https://g.codefresh.io/account-admin/account-conf/pipeline-settings](https://g.codefresh.io/account-admin/account-conf/pipeline-settings){:target="\_blank"} and toggle the *Enable Pipeline Templates* button. The easiest way to create a new template is by clicking the "3 dots menu" on the pipeline name: @@ -251,8 +252,8 @@ image.html lightbox="true" file="/images/pipeline/create/create-template-menu.png" url="/images/pipeline/create/create-template-menu.png" -alt="The template menu" -caption="The template menu" +alt="Create template from pipeline" +caption="Create template from pipeline" max-width="30%" %} @@ -318,8 +319,8 @@ Pipelines that belong to a project will mention it below their name so it is ver ## Related articles -[Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -[Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Pipeline steps]({{site.baseurl}}/docs/pipelines/steps/) [External Docker Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) [YAML Examples]({{site.baseurl}}/docs/yaml-examples/examples/) diff --git a/_docs/pipelines/triggers/dockerhub-triggers.md b/_docs/pipelines/triggers/dockerhub-triggers.md index 7d0e8079..1268e4d8 100644 --- a/_docs/pipelines/triggers/dockerhub-triggers.md +++ b/_docs/pipelines/triggers/dockerhub-triggers.md @@ -75,7 +75,7 @@ You can use [Codefresh CLI](https://cli.codefresh.io/) to setup a Codefresh trig First, create a `trigger-event` for every DockerHub image, you would like to setup a Codefresh trigger. -```sh +``` # create DockerHub trigger event for codefresh/fortune codefresh create trigger-event --type registry --kind dockerhub --value namespace=codefresh --value name=fortune --value action=push @@ -87,7 +87,7 @@ Trigger event: registry:dockerhub:codefresh:fortune:push:107e9db97062 was succes Currently, an additional manual action is required to bind DockerHub `push` image event to the Codefresh `trigger-event`. -```sh +``` # get trigger-event details for previously created trigger-event codefresh get trigger-event -o yaml registry:dockerhub:codefresh:fortune:push:107e9db97062 ``` @@ -126,7 +126,7 @@ help: >- Now, lets set up a new pipeline trigger, linking previously defined DockerHub push `codefresh/fortune` `trigger-event` to one or more Codefresh pipelines. -```sh +``` # create trigger, linking trigger-event UID to the pipeline UID codefresh create trigger "registry:dockerhub:codefresh:fortune:push:107e9db97062" 7a5622e4b1ad5ba0018a3c9c diff --git a/images/pipeline/badges/view-public-logs.png b/images/pipeline/badges/view-public-logs.png index 395c40467623295ef04ddecb3516890f120b26fc..5589bd6235459172bafbdb377a9f882a9469a94b 100644 GIT binary patch literal 132766 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

6Cjq<*SLQ?T5r2nboD-+ZzcBv0(Uv;a=nW{ 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

&OqU8$I2;p4J~#YeY+DV^#N5N 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

+{=%id5~}mj&)hoCJE{^7x=f8b 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 VNzi_qC4mEyw79%jsfeEc{{fmuy}1AY diff --git a/images/pipeline/create/add-pipeline-to-project.png b/images/pipeline/create/add-pipeline-to-project.png new file mode 100644 index 0000000000000000000000000000000000000000..41fd8dd8fd16bb28f966e0d13b6925df618ea868 GIT binary patch literal 36802 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 O-R0uw?obU!CjSLE==Jyj literal 0 HcmV?d00001 diff --git a/images/pipeline/create/create-template-menu.png b/images/pipeline/create/create-template-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..1259fa3eda8a5521bd3afd8c1157ceed65274290 GIT binary patch literal 21069 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 CVyjyK literal 0 HcmV?d00001 diff --git a/images/pipeline/create/editor.png b/images/pipeline/create/editor.png new file mode 100644 index 0000000000000000000000000000000000000000..cea04bef5ffb4707c0cb18e8dcae736b28d68c66 GIT binary patch literal 32244 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 DsKG(A literal 0 HcmV?d00001 diff --git a/images/pipeline/create/external-resources.png b/images/pipeline/create/external-resources.png new file mode 100644 index 0000000000000000000000000000000000000000..559439dc4c37cb0889bb767935638b7552f5bb4f GIT binary patch literal 23714 zcmd43WmFtN(vEc4b2=2ihf-b(neF^R^yXbz9=Y8+5 z@6SEwzW3a-XJ&V5dwQy>tGdg2B9s&)F;EFm;o#sfq@~1F;NTE|aB%SU$cWF7%HVJ6 z&tHfpvXbI(u$Rw|&XS~O2#TYWwhJ5_8qUiB50{yZ_Y6dGm6rdCw2AT_^8>;c`TGPo zI5IeCaS=7orK43JU-j+4Qy560j!P!|U8}X+wn>JP&5Y=b8d)kl-CxjOExb2zDs&Hs z>+gS|8vOY2zC*;u2yu((S5WL95^F#r8$+oQ9dan`U#iqZl~#^H#Dew2A4fT6u%`w1 zSCo`J0mylf!vVQ*1D~pE{zL6UuP&d}SCdxkk(APjl+u>9+!eyl--%}2sV{(GNBS3V z;=0z$nX<3;{0GF3rFyw!C6ax){6BQ#l=jD1(%j}il|zx2UR^(;`9jkG z;;QWp6lVHTFQADzN1_;s0*&Aol=f{urq%z9|8-6Ff(ma|-}w$tz4o^JKMV`&d5D^k zsir?oM#jH1&KX$ewmVW{^&?38cQ5@8LhH*9Y0J+4SEyg4>iP15tJ*Y%P3q+Y7*rZ5 zQH9PC(IOmhg4$;c`!b6nMZd-(_W8h_ucp`v`+^O)b|-*EFD=A310 zB8*B-UFJ8296~#0f8SPSr#m64&%%RSYG@#xdE*Z$IKx(sogq@+Qbfb(+Ssi6k?W=t zZQY(bOmr;{*$n1g;f^JB6XHDk&g*K`uP5W_wa|Tb5CbEOYd zPD{-GL{_fN1>+Rtl@NiCX!Z}^f?g*Xh;3bcx9!5RLQfNdrP@H#$llkruG#A;t}KyY zRy_An_SCVlZAm7uNTi+O%YzjNOMn8v`^e9C?7kNBt};ya9j`un=Dk|ZdH$0!M_|2W zD+X!bZ#IAUMy9P{2pggyEOJ4rz7U!I$c`Z+NZu<-4^{ zRMZ&l-@)^G1M2fvTdBrLp4NWjK)@-5#{$Qd?-_;+7!Yx9e>l#edA-%OjT8&5w0e9d zr(Q^)rZv*W8{9jTVZ*&azHyH_l;cm@e0@61p{Xwhdh%f1-+pz&p>4-rpnU{;`!nAh zA##rSvTGSre!4r=`lb`cswxQS;=W?%07!oR7qiz229Owt8l7sWfXa3vLbtu;A z{>tSHNw>sHcxSSFVa?BeC`cmX_5C(jCE$}m*Qr8rn(J=tTUESO)JTJz;VbJt?mu@B z{@DtYledi8eS~kYWlj|cFc@^<*(75(iYyl8d@WvCSM}NICXH6upbkw~$-n#MFs^3b z?tp^CdSWrgwkmDi6c@D8I_9^>IfvUh^gvoPS?Q$P5Ze~wXG85YU#f>`w$hVs={=dh z2#*T(j95vVo1&x0N~Wg&Hx>9*^`75ZKkoA!4|SW%X(>M%RZ+IZW%d5P?n~#}Pjdz2 z;~tV`Pu$aboNesUndCE+anRCAhXh#A(iRpH`I61wk7eefEi#>rr5{-DO97n}MMVI` zg59Z;petUYhsemivoX3xq{Tu5xpbj~lUbaS2P+~37l+N;6^>+d0&yD^ysI&pJ8CLo zOpDc|&suEJD=QpCd$Y|6@Ho9haEX6^3r3>OosI5Kdj`7>#*7wooU(P2o73rlmW~|< zLMF{T;$~%abP)Zp7>WW66%0j{f$g`~*(`;`m9S`Z70i`hKNri3Z#P7Bg!j?)I)`=7 zjX*`EeX9@NH+WO!bX$?pC+NKFL{9ZRm`R+=!F$chKq zBChPVVZ;Kb$WAt~4?f&EwvW@eFRchF+wnjj~7e$)9luDXQ%n6raQr*izN$3Gp@@)`&_dd zs&vR=Za48=an8zzmFCbg53nR-Cmx%{D~c(;#3^r5S^GoK6;8If3XpwjDp87%i!joD zGhZ9RQnrcqtWR#6BdJq4qyn=!q{N@|jqDg*NQnE5Z#h#T~*L623MD3M0OBO)7G@68GtS9Jk&CV<=ESKPKvkcbnj<;#pv!Wd^ z{x-%kdVWsg^3oxzy2?pnN%7+QrnLBhI z61W(s(2yKu4^~x8l<4bG@r_2^u7;hmZf|xHm6q@WxC;QiJd2Ue8SKXxiFGB+<|FT^ zuYwwty)uc@a_v5eBpL9F}In^Y%mZqSs~s(vqt%9{KM3PRmJFjX{Epb zt1<4n^>7ilEyw_WJb*GWF+edY)>jk~h;U@HN7%q?5ufntO>3)LcVv0le`JQ0;) zXWdZm0cE0qAy`%C?5jD|G2@XqWGQhh@RKuV)oz0PVa9!&^OC_8aq1P+Qi5_IXTg=@ z7{(XZ3E>o?UFezEAx`&|C#9yE6$D8>-#`Oc>`iTnf_m+E;7@gAuh|2_S_cgO-2P-l zw|}cU;f3qE*+?RQx4c8-?q8Q;>0xW>H|vGodV~n>xXW@CoV*j9Xv>|yBQR(`X3@x3aamLBlvnMR`Yi8!D>SojMo|x7TOd3 zcCoOTS9tPHFBkBHfp>1>?q6Rt~enrY8DDl66|#839Af>n`qXRu$YK)Iz)Tt z-b?g`^Svw=CGY8BRP_d{l1qC|D+|0I|Fo~Ai&*I}*86)AZJ$=9Y)w-`w)4EY;jyA=+|u*KKxtaa}fS z^SE_7J=y1IP1hV$BK9O#+`Sgbw-d)lXF8Loz^_* zV!@WkYw-ti62YIu8e#0fJ}IhFmvJ%185-lA8+IbQ`~4Qj#9DXC zo8{&@x<)n%M(OpA4dNq#iDt~BPn z2Y5`ttv~+P(-C|c-{{W9m({p)LRW3+Jle^BF;_9hAOyY5yL|#USXjDYud2RXhudY@ zSR(Z5P)9B`+bvnnXy4Y~@xOVK!*^|}pLThB9183EwNU^d=8j_#u(xpDaDM_;*g*YE zPkE|M^#SwL8iPw|Uanp?bc)l^N*Hm8`Ld!TxE9_3(-5km;m1eCFoL-i_UL25>DuZf-(0VU;rVE3^7&k+P|vuXscsbxfEgPWIFAMw@9(2g>96Agv@4&iQglr z`Sl=uKoWumU6Xc>{)z){cciX*9=9>BBu{1DM?vbs&{{gSZFL(hA=bdxY)V9sQ$E6fIF9Fuv@Q%9dM7jV|Ubs2q zo^on3Zb^C>mKb;22d)!aKaT2bHv!Ns4rH$S#QA_6=?R-H9a$gTfLXqP;|np^6R-*N zw_{=@M+>5vMdh~M<4(TNo-%OXwdJb*yzDPxo&W%B0F2@@=ynct@NHh&g@&}7mk?b{ z=P1t!KWpLy5Bo51cG3Jo4Wxf2Wa( zz`*BZ6GI~dpx9Pn4R`>_#GwP-Dh~reO&9G5j?xDncuq5{Oxkc7mmd(kKDJ;N9<^pSJ8ygj|O`d7?N0L*X`z z+qeRElkHH|8_I@_Vl<||*^j#EDq7&*Zjb4-q_!oJ&6xb)O^c`PBojd>(NfbLB3BNC z2UPu7(+2^}tK_a7KR~1Xy&M09W~PSSjF|Z7$OQz)*09)j24^+UyY_s$7Va^-1$bd8 zxEITvn#`^GmaM2x{-6KEbkg5EB{6+6-@@(g`yDj?uzp#f;KS+KrlVe4{MRnm;Tp8! zx5$D1WP6$K1@_U7@u*R=xBPo((?Y|TQ%ie{?_|vHGZHy`dkV7{IazSN@ox$|T>G-# z)4;g0RE(pE^kSub%>w_k(#mURI;p&TVcn1m&$NlFu2Qz~@@L8S4x`QDtS$bTe|U!& z6*YhM*zu0q?PN^ej&b_{$~@o`HN5yMu*98ITT(J@x5mq{| z(>NCRukcRpf5KB{+)b#@E&dP3r*gJmg+0a1TvgFAI^Jid9S7i#3ddR2E|m zPFf{b=r#%Z%`+3kNUSRTL$b|l^|0e{kwy*w!;JXGD|qjQZ$P^FE6)GK$Xu5YJ^$Yb zv;E%>?EP;%(Y08HJAo}BawRuHNJ9qxCDAj*O9z#w4pJb+GQb-ctJtQ3f zNvd2le9Y_FY4`@9>O@=}kk@SFzqt$!THB_9c?lfG-ko^Su5B&B2jkClBJ>;xNeb$W z(nY1#+D~H&u43&L`6gWvBC?jk%(D$mQxoFAX6xBhwkyh_lna@%H7CFy`H!vawcf-_ zE5lbMHD;?&B(1uFo2hJ{N5u@bi#iESom6gvK-}V-$HP5gE zf6GS|F!5)CT(^ue=REcVD>!?(SYZDViET@%Tg5QXdm#+Xe{9B_DtmsnWDL)LF<r2XU2+ujOUOTmI`E^M@@V$s~iv=Evo=t(3I1T6@*EJ`^H4MS2qR@Xc(c z_XDrX76CUkEH#RrcD+^~PoXDoFTaJi-5*F?-L`9}+qgi)b zdpBsBP_SgUx#WI)KP>rR?`xX2oPKV#Ie$K;Zm7RD%0N0^W0}pLJhUk!q@cl_1yRf? zUT@LKLPx|L`*HikQ0Ze%C7Zj@^HkzL@dI-Qku=WxH7G3=1RK@B0e34$*=x z=*^umbj^2TjeFGWRyB@#9)=3)Ew%1MHWkXkmhoE%jgSsgJI2?t40|wUk(!LcIBR3; z@<*#m9-7gIHyUZ_yu5~~tBJJ*JQs6EM;%VqSE5PThK%T?Ez^Si49vJlpPcXkdQeKA zpnA`}&{T|5)xIoG8#@$~9x@-;6?ImafyABi>M;1)#p?!g>{SXI;0U@*xasE0%Ny4k z7An7Qv&lNO+%1N9J}&OIlwMMLH`;B~kv7+0a&(>A1+mBkAO4tg8q@wMu?X?KA|YIR z_|OfV_Ce2mz+OAWE_Z7ab5q;pgfR*n5XXI(ZR5qTUUoaB!N5l%XwE2voJ^lF+^-@ih5xd+P7nLgC;=)p-XI+Q4P^ zJS{yHjf=jdy*-cGf}IO|(rnt=woE&R{Qa=PaqaJ|PsDo_HMQfFjHenFq*r!;>DxHJtWz;0smtxp!+^N@4QF?5uzk5<(@ z^Vv*kaCuC>J)H~jDf+aT!E$w!4(fB3g-+s4JZ_hl=;~g!xT~Kt1ccoXkv>`D+&h#` z(#$ND7@!NAO{2~o^W@neS^n}mU+%az;Mv!tA!+=9tc&{?l*T926Tjpij^SW3nVs@b zklJ;!8TUzV=7uu)(bMlb;;PfoJ^DHRuBkb&1t$HA(zwRtmqnEc+YG&7upO|h0up)+oNn_J#>y*-=Y z#STFEq{6KLu&3YXC@t>~3K9A{9Mj-nsgTFhDx*~z$90Tg8=`O%KHW5Op}!YKAwl!= z7c9b`rCdH8`MSKx^7w9=^j+b|=)Lur^C1I3wwm|?f%lxtzj;gG#sRdQa(&iksF1EOtS}2R|E16KA80H;D<^x3=+o;L|vtyTMu8p(*cb zT1|i4GK)cbCX_ed$vLJHyY`jaUFatAeV_5o=~Dmc$IkJR9*3#Tk<9KN$Ht(O)mp&z zwj{^S0Z4GER~OA?Q7&G#x-I&V^usxi2;+XX%4qClE+eh*Wb8susf$n-K-=Y}3qqHB zcg{@Wd8BP{e;Gj>BSTQX5}FL#5Jcaf&g`_oWwQaJJ~=&k;Io%rYWrryQ09z(67Mzs zw4L|MYoApxx?yLDu$sSIky{~8r7M>UysTIeP0xto_5(Oet7fa?GzQ1NV9X4`e47U(o*MA3Q;*zk|BPMbna%n<47suWI zy`Voa$2zn!->#kIet4Jwm(z-PHr&biSUbPT}yl2uSbi1o}2Q=@v+0nV+ zsxmoGmOt`^N{8yZC5{jwiek_L!ex;#cK95g_)Z@fq?Ug5xXL#e%S>ro18Y1B+qwhD zs;b+=vKVD;9rM~OkF#uJ3;$I35Pn)`uBsXR+gmj1xv7}MY7Qf z$=zJkRB72R{q6b5?;(M=Z=4S3CrPV57tX|R*RAw-pI|LAFxlx z$^}tzI5gQM4G8pAZ$22g=oqf#M(Jo6nz%Wk?$!n8=tllMz?7V*@kPpt3P`@ubKOHt zOVzvU>{+?*>^WMycqNq85*=d$LySQORuOitASMg31e2t_@v?m6YP~t&Y?6`Y)h)W( z0aDcL`WnF`9WF+CTOW=hkX5N6Jigs}IesHFmG_&5rEms$+|lzk6Od~mW#_(0$Vy{A zF#WBq{~2zjHh)ywGAU;8Zb|=L8y2hsq54D*Kq_=`M{o%q*LCslAr<0DKrQX8A@O!I zy#p_7?|rz3;FM)dLQZMk1%?=1Qn>gKUoW=sa!+vYRO0MxGJF*#WGwT_aLRF0n};5a zFx6tZH6IV2($E;|X`S+xD{pS`)&)JwP5-mp@TT_`t#!rbQ`|ePKS8wFVWqNCLC5>f zvnhp!ZdChgC%dYX?7 z2XRox`*j=h%#wyU0TiYMXlH@)sGZd<3h@(%a-!=EYO$mA?!@x~$hN;mC>8e}>N`s9 z&RM8u62#E71H1|beRZ9zA17tjZV zDX!^_*+^cy@xeMChkV$AY4vnECu#x2EqmgKdBFV&!dXZtZ&L0nTdyRyc1%U>x*K`H z*NnIBVHAB%|BF@hIE!7;nokX+OO}%bVghb6A)ED~O~*J(ikaSeT5G%qpRc2n4u?=r z@_65(lsFsrOf<7KfbvWfPwqF(S74n7Snl0Go9^8+CbyobeQzk=}YdWj{4%oaD^IJ_pCwS851bJo+JY&~J z$F!Nq`O9+J8@xD~NLc)oO`en0va^Qqp^Tc()fzy<5)^-$T`TmuU0Z1J zNBUsr&9-+JdNUbQ8mt3k(aa@Q1g<`kI6UMM)Hr+R0bX|x|4n#|MGtA5Q9htyV(y$c z*H(?@i?dtiTeBVVpIT3jMmt=A&1~6SRX(e)cbF;ir1?;%ufufGgVVY%xUCX!1o8pz zUVlHG=T`Aei?VO&0=II&ZuI564zg;~s=M1Gg*3WdJMaHc7`FLO{w8Jn^g!s}d}C*z zOPcRB(!2*d`-S5l=O~t@3%IrEn$b&iox3*^klm??bNlnGPW#soW~;qxw<|i1`{WF9 z5bdY@$74O8bLAxc?4HJBKwsiD9n^7XwsB(r=M#j@byRH34|29P(e2GHlyfC-U{IGB zb6RC$Q^>R1*d6_ZwKBkvlhw6%eLWkq?~`Td#w6s&{rzi{MtrwBRf3TXW9x}KA_lQ= zTEE2ABu3Q>&n$=k`he~qy4sFVp79x;ZN5zEd6aS>j`#5YuGd$RP+lJTDF4FOLMGbv2EB?AneaH8I)9Ey&5xpb{DC5U z$i;>j>M7W`r>Xz&=g62o8FOmj#Us^v{4z-c5Y_9sr?mAC8z~c_uJd=J$J11A+y2kM zSaHWnp!5S>{#MN!%_*YbNNT^o`HG;Xp`pyNDS}Y<(rAAS12`Fp442>rpk%lC^me1P zw472&{Y^@Wns|YlhMLlI%idXd9v$uVkI64Lhk^=P3WFvzWrij-{g`XN)~tN>Q_2m0RKBeS5bLP;yfC(dmar zArFrV7N#fD41m{uVS(#T$flL~n|>gU!6h#W4;GHs294T#dx~l|K2f1Zk1vdEA(xv4 zlmlO-$xs8~0uKW8l$D*#gsYj!{uKvxS*&yGXp4{u2A=8GydC!nxv&aonNlo;F2V|b zIuf4SF@EAUrcO9?pw4!~QI}@mp@Ew`2q21(h(jOxZ+s(A#0w^^OuLjW7VUKm|I|eU zomYrkKCypvtq5p=8%I$7!ek}6w{D2Nww{Lxu$%|_p6?;Q%JUry{6ePll^vT59vLzC zHHl}Wl7!+~@V|POlCt8VB$`oLAs1g)=IU@!b9Ui?&w=GKf>@M}C%Nx>Yo1cA)IUrP z!IvWASoyql;=)+ZZh;GIX$c@TAb(qCz`4$kGDejTvtFj=qhG!iF40-ooagr zn*fm{U96xf(T`84;uR)1uQ!mz3u+<6GvJx=Gdfz6RE7UN`$!nOx{`C+c=&RYUQ zhKB)q8d6U?8*E+cFI|7L6@EkmZFdYBLQdC%-zc6foJJ}Po1mr1?@W-Q?;te`jZIZq z+N|i@A*hzhM-3T2!=3Q0!R#f?CbuR$f-GKkAa};5?jg9d3O1ive znfy2E;t1!przF0S*UAtwE^A>%z23bnhns&8(Z3d1yaFnLp&V-Le5`eY*#H=wesa2nH zA6+>$t#2=zf20z%IpKIy?i)vCx-T2on(tBfq-@k7;oI}8V}zElLi$btON zPXs?$b-o7Z*n7lE@F;ztf}Sgk(8N*dG;w_l!15LG9ia-Lend)eFKY-7w(@1ZVchz? z4k6RjP{Yn)$vw+6fxmV2A6H!*^pYFZ7VXJrPLnDbbLA~IPs|{=TVnsYVa~Hf&qUb@ z(IUxWj&Gz$HtxxFE)Q_k_6DKGMom*VKf#;773QaT^SLM9d zsv8{9`~{jOY3(daO8tBpAUQR`WIZ;(^WKdC`s#BBiEej|ah4uvcRI5jJZPK0$EDqe z*{ipEYBMxJuD#%qR?Ay=s-37qvW04YRRy%*t-!r6TUr_2S#5oNabSd=P%iTdc(1@d zva62Wyp2$Pb4=Ye;B}NI@cmCWI#s?YL4Mv7UqaqvdMeddHFb$a(ij!5Guk;}^}?XP zAW}--GjjdeL&r=Gr>1S(cM%Omu9_?ZJqMoIJc%gU5tK9lKLTZA5%RZFdwkqcS2b2! z@4&yZ)r+jr_vg!`cbaYbEZjE(wWshu8l$4o!rH2?=FBVUPy3*ZLO2rRdp!%C#N7Ia|?!uqVB zP@r4F=HZjG@?7#K>dTJ=)@Ns#!L&3#)?d#$P zhYhAXM7iv*1EZJWYHIKNEE#r>)_}YHubj=v;1ZB~@Uh-?!K6hsEno7Z9Fq|jbr@s* zMg*gyY#Gcp{Q7-f^x5^{>bJ`a^0JHyAd{i9e6ym^02NO9A!G1`uOMoe)p8l#VqYkB zCVP_pGM>cwc2?TMw~S5q)4AeSg51&l+z}r?HI7q6%_tFXS29|dX_8!0@BU)# zexEpv&+Sfx5GS>6zO}vccAqyf7wOV={hh>Gdw4%7ddYNCQRUd$S8kpd|2`laKaPf6 zS6Iev4&KcXI-(lD@-pZx|3wyem(R8!*x!Nc?Cmtbk!>2s=W;K4#(RFd#m(2zuP*FQ zwGqCT?%|hFe4+aW9Tk2c1kM*@3G;y8Wkyom^EL*$P z)I2_jWlf3GjpuU<62=$1vr`j;p~Kd4_to}3`hymAZu>G#A5VVrx6+AWHlFh?NnZOW z^U^2vZdWX5bVNBiQ}@wCQyu<={)oLHF<{AHK?{z~=18dATF_#$l*2R^vt<5ZipE%$u- z^K`zoaRQTZ2dZ{bGe{k$dJU3BDV~_m2Eu(f)WqRxXX(KslVK+i*zn&Hj-t#=NpUtB zffat+T?_AKP6;6u8f=BgQ#sv5sWr+!uVTVStcO;~sO6+n*Oy3TLxyXvJ?SbJJ6pee zHFfKriC}99o;O zAQpL!icDWE!o&GoLLI*|HOSb_`pe^Bw56ImUvCk|iQ(r_irsbVt&i>|L#ESSzP8i} zv(p*;4ulyvxu$aSWPcKlfR-0WIAY}pdLc2FyYaXO65U5#g<%Jol7i-Lscgj^WO-9p zJ<&vqak1Nk+R!UePEw~cJ!yOY_%V1%54E>~T3zqF<2ELN5{bh|TY@=#kyB=Mh&RRN zg#jxo|ELXNZG~lu30%@)&S{ z^c*tnZ&^fFZJmyoJXG#_I!OqP;0pF`rR3moZ1Nan3*|Nh@r)U0dplA}JvF(br$gzx zACJ-Gq?pXW(@~#aFLcD0r1k#R?%vR35(MIi`6Ol%ee#2%58l{H|2ovl^*R5VOPD7e zXjK&R^WLvfa`U>SnE3MlUb6czIKYsXmtMbRa=aAwl+uX_Y!-xbl}tj`<*%U zvY>*dq-_E3lD6qGmoO9|wMxcp$h1EFe&a#R&ez88n4%-4BgXD_eY4*4WZ*VhX7zVA zPlXADg0!Tw`H(F&!TQZuR%fKj$WRtr*h7PI^vE|&j||s$abZ~*TwVl(%b4baXx-b* zOk+k;Q6J=TJ1E_=`MxcES9KXuB%T;Ed`!i)M5kfU8_9n=z3-oGW6S&mmMV@p7%UU~ zl4@r#GBZhmC*THuYk9VCR%od4cw6&?JC34+|0A#m8XoPdWlm+NrZ)Ld4>-F8JVv@m z^1o8Ay^q*j(wAEqhXq@J6nBO7;J%pFc$J4oZLXBd+;p>NeN+^Du7IS~OAwnlK(_9q zX6=v-ulpdY)yOxrZ8~_-S84Wx(0a>d{>p7@=fgBdZ8o!#h7Rhmz&_hA-RtZ`X>>$# zyic`uti!X~%&mi1Ki3_J*H(GsSWKN4)dg0!DGZH#9cjIu15|<*{6a@K%ld8R8eBVf zb1W^<9jlJFL+9wHN$6(pR$8L5G&EsEzj!%MZGbU_hTdpD(8PSIHxg#)Xz@5wx5NX) zRaE&BGSQLZbb6}$JU40uDG`cBNvd5)vZf9{TVDI>+z?Gb18c?9HwIIDe|Zxw%jC;m zD;poynZIv19v{-N=d@pR`P^4O73jKzp*MWMb6YvVRG>Hqhv=?1@sJ|B!0q|T+N*Ud zrMU?5TaHmGv?-$2Zn{aeWT9r^x>EKabaUQG<2s?qdchteKkS~yP63`O@TGBO_F={!8l zkIw8H(BK;=T=s;gPPE7B#u3V#pus`gl}jlTXZabm)?#I57Vah!i8Vl{lSAz2{P=B` zoqBu1U&mZq4Wk>a>p2rcAHAmfob;I0a-0zi{VgUxVeJ?4m$C~0+?q^ zmm^G414LeH>JS=3DxHU@m-OdTef6mY+sS!#au~cQrH4$htF^6w$}(|#`%H6eds38X zUUQY7CLIGKm1v0DG?L5Z6#?n%zT_}+ElsY4rq%o$i05VLfsQ1PO~!5y&dB=Nx*>v# z=E)~JBcX%kuQ*9KDDUz+8i=HdAn`WZ{B{(w8avZ2*Ah~MgTJp9GHydlTN$rso$Q3f zNR(4`n)Xjp4DH*AT7L!W()QUM-Ic z5qYQUuZ}QSMX&p@7}U?`=>pt8khL$^Y&bRLI~RXPThdbLG>XYl+(~1}%4`E~>dfVQ zj%DF*4pQb>#&qtnk-RuMyCT>uFbg8oz)_If4)0TRW<3@ydVebD9IvXOBjaVFyEIqZ zsc^cf*B9)xTtkls^mmn!Lx1&_Ov-t=pRMU@?v>-pQEY;m+#?IhhZOO0(oDBr5yAyS z?XOqeYn0y0FxelAtziIM=3Def z! zIfU9%>rcg@(-qAgDr@PDOmdk%k9GtlLi=Y1reGb$_usOXV#(TveXrgOdhp%+t<8sb z(_G^(t;!Z7a6B8*l`-(*rKmr^a%e~OcuOuddH}cZ$pyKS$w2aCqlA`TvGA}3OhW{J zXoqxdf9MXhpYCU>)kjVHwWn6yU8u_ExD@~F7pfpC;EkHL>Hs?rf zfkC5}4a^=^WV6)fWkV$L2|=T3reI-7S!es!3S{g!pkpxg6l1JdHfQV0ic!=paV0$d zQkZOpX&~bFX;jeO2kEokNOsB}4=slaT#&JK9zOc7#~j~$v!zD93+Q_V1!^^eu@lD_ zLv9&aT1=Yh{ZcYQ89B=Lv~f9j$Q;h?fB|4DZw2MK?>n*IPklYm{paCBpqzGiF#Tor z;d_}jI)8A@XZ|t>kz_@=R11G_3sNpMIXQW1KLQ3%u--lUxsy`}0({T_U^hyd0=dR3 zClbTq{C0X%%F_eGJVjkeTRIu8r-eHRzLek^4`tO`Ezj+#PAHQyNzjOB)0^f}`Gnp1 zLPmOmNJ?WAnGjdOa=0ABR;w{2`}<*dLr3b-n0p8plle_Yk?jHjd2+TCvXp|oG_pyI zpo$cDM7?rB$#d*>WYZ6lPMyUQFqZmk=Rn!fG;EE;z$(tviWb8=j-7|;D;!A;Mj;Ph zFSQf$K%wS5^kaMv_jXZZwslLX_1+WgA1jAU#lT-uCvrz--rQpNm;627IoGBb@p^V^ zckL7SK>78bT4P!qI=Yw5N`hUZx;n1(ido6>}$84Rfj56?0MGE89 zM>P_fTb~H&4k|Wrc+qo$j-6TO4X1|deU>doRN00P66L~~zZ0UGoaVj$JWj*(>O`bfMnj=a>YJ*a5Or|-xp;^CoR zCO{k+(oI#=5n{3thyna8b0H*NolubDdE+(vsJ*C>%AhxVa@949HOE_f}YG4++u}yYl@rp|Q#n4Fl*ha)*r}Mn; zEMX;O)^vZ$H{bR{E^Jd&?jd-1;B3=SS}y~7|KIP>4P zymGoN%;mxC9}qF8>WR(`IRzw!;A4q?{d#0Q1;nVB>`RlFPiG_u5LQoqRJQ86X6grJ z3$vr ze=1vYQT`Kd$+h`d>AD$}m^Mo??iQ=x;={spNWBEByOnK?!fBd3Fs9r1I(y&t2#TOG z4e*>fQHFTfNascS*`nur$!hWJDm#nW?I-iZca@P_O&+%#A|v2&HN|ItugGBIiEDb^ z`4FEo*s(^G?ZG7>C>YrP>}&B@5_FTZ+=%bzmtg?N2Ap=@n%Ep~uUz+>@3y+(%c3O? z6Um-Yi^*MI<*L^xamEJFNFA zzkwJWa6w!XtGM-ub=)=PPHSaWUtJR;#hX)j^F-cxxpRJoP+>LCnlUqGua}!nddN2t zwfM`5vmT8C8#OVLC$)AK^mA{@fo$LF63_4c9q%=Sct%m7j&f;0LoEVN^@DD%T>9p)w<=5 zxvqR)kBc$y$zF`^@|({uQCIY|{adRjYo9P&>g4C;J%O;&^*LciAp`v=OM02=+741( zV%R!*sok|BHrM&|nk`gl3_%e_l&G8g(T+i{Bhb9nE7|>M{I{U~#KH|}xCEhxOygGl zYD3o#^Ma4>sw&B_^Ms*_6()*t)un}>2&&k~BqQE{BaPT}9)J$vHh$#WIAKXG+kWnv z5-3F1I>m7CKc8dU$nn_RU!DWkqIwV39VorY-^CivLdzxSmOFw{+Ic7WDyD1sto}t6 z;-|XeE;mZsa{06*z|(!{O|^75J8?jkbjloRfz3JfO4O3+lBn*9oRsCy&mMR)h~oAf z7k_r(Ccj>CpKuz#(Ml-Ia6YMPtv$7xSTW7Vr@79kAJ6~tt?;M$*epVTs z`a6XI(dS5}lDhQX0evqPzuz9Z^BW?Ba?!6F-hdp#vul622e)1q&ygthU6wumU?ubj@+Ds?2x z-~TvpWR5Ku#NX_Co)-V@4lc`AI5wZ!9 zdVcuydsq2~cczhV!0Vr{B@_jG2N$0C`b=j@(e!QIK@B6(bFq0)9Lmt-=hv^;&@C{HXT@N*W(ZF$anK<7)py?v)!B@Wn_T4h-Ox%lQr zI99*)PoKvL>%q2Lg%es~d&o`8R z<=+2P(w!eU7=CY58(t<(ts^ZctzgBQIx97@suNRcPzGn>OoLRVmn@3*r7FEiO|{Y| zU&nQ|B7NiYRhzxc+)y3zewts_y=fU&)=z^^!|xv-;a*cZTjpBkdbwNpUtXXmkDguX zM)>_KxI4`xn9qJmD6LwiURuqLUS8M~B7XVslk}d__b5s8`%dJ4`0KiBx_42fy|v>{ z^D?Sakr@Aj+rt0`h5AC~d`iK60D*Y~675G2d!@J*X z|0%&m2XY3!5cfa4!96WOX8XSxgH`ITJy)(5nn@73CMXGQ@53%5hk};FsfFNESjE5T zx%|VO&tg%Z2NO4_$2aKt{Q*R{FYg67=iBWPf!cJ7nqAbCcAnuT8$#&^9P%mzRxe>^2d%~B%&!GM4IrqjC4P5%M@bJrcPKbBuM z0l7#fc--UbQ{OEbuK?E9 zZ^>T2LKcfOma5gF)I%N;k+1qsVzA*=uTv{}0`hku!UA@;z@a!UoconDTE8utvM9Jl zmT+;hQpBxyc=7*U6+lNr6t?|tW=07*N2-zq7CZl4qcoyVdErP=3wq=&ihFo1q=Ivy zL|K@M9TZ?hPL?K9WP{*5{2wyfK)p^{jBjUVRG`yBWOAqGg6QE}u!t#KK`~m7giOHs z+n@IaKcS@as(VnLFIcmeMsVw*!i=Hojqt5=|J8+n2wv!VmE74N#KP-YP&_{40fNtp zKuenzGRv?MI#!X(DK@5<<=$9&V8^X}Pug#6Mxz6fiPqrdtVXvHq`>oTfe zuxk+VFSR+v>PB<1wdxG2A?oJCOB4MZ1`kgzQZ%M3!XR`7a!`T}o?>f!2^sMCp+;r} zMNY_D9t%zgAbZ!Ed_?PV%r?}u^G|tXI3V+|B>mMq^R-hL@pm6>N8=N4YV))EujLK- zuo<9&9FlT?6of2-r?KYo@CQp%%(2jd{7fU9{|rw2Re2sJ6V{aa&XQ&P>0tnW8ikLs z_khR0++;I>5-hZ)5EgLSaSQ5j-+)8thG9Vp7gnrAS?|G*tQc*X(e)6;ZwWayI;}2|R_y4`vETSxP-)m5Hu*5_ zEA0|Zx;mVcMY26f6V_r{So8;-p5#j7E?B}gCpe|UvIQ5PP_GK$$HJ4zqx<^7RwjX z2*TMgC0R)Fy6nzP+ojl%ww-ogq6zUy6q5^0py@XK0dT?s?-&^tRl6?b6=2(a{H=$$ z&@wFe_rsu%ry|3u*~B~``ri*W*#tQ{wRU(dVT7wxG90Wx|o^YZO^fkcxBDHdO5A!G<5W#Z%OtMC1< z$!ZlVTYU*3bt{zFq$U7@I~8dHQ#hwgRcVb6IE9%e5P6zR68R*-q=MFpxUNQN9dMeC z-ruXy-G~~m2s3o)DHG}`TYUNR6iZclki2>FUdbKwo1yM?_kcE|LbS89CzGP(o#*)? zCPCVA&o}q*r%fJCevfE`DmT(Uu^i(ILvIpSJ7-oe{oUOb-`xN4D{1TMnwpomDqkBk zaTCrp^Ldx~)4n~h*TX-~?;a3!`kr*hWNmkU4GH)JrLes(%IiQX;)=Je+D)0a4D?Ps zmJi)r)?m~$oOeAL6J-uHDU$m&!)`pJ`yu?{*hZ~ONLGFo>vCsuH{#KktFb~S-0x(b z)_=Wzru!UAZG_w*lzdyZKno$oBw{ZuH{a1ZzWO^aeLdsEfNiWvZQ#Qg`!w3xy=Qrv zAF|m!qADwcKuQY3|f+ zl=Ih)KN~=v&@WEFP21hsO!d>ZHo^P2%`hblm~a_Yuh>8Pwy8w%yEyzAO%|4 z;;Sa3;E~WS4X%~nE6+R#eC!_Z0KfJOb|}VD>V`!f-EI4*2lFo7$2!@L+sM)ASUDK9 z`dy!dZZd~t5`b@$l%dW-1K2VtBU3$i0ReEIB~4$8Tu+>itQi(Qn2`2dc1w>-`V-{} zi0(IseNG(-0i0X%Lw6uvQQw3ak>KA)iDLNb=Rs{GiIq3qr=vSQMJWPgrcNcqG)Ym z6h+b4J4H}6LLyd-YKhu=#(3QK{k(i$KF9y~zrNm_$M3w(>vx{l=lp)KuvY^(2jX7k ztP(d~(=&56H!0S|-X$6Kv_O84Se4*N!$343{l#FO|A{ElW0NV;S`tUu?^EvB7`)n5 zRUyOYmg8ikK!#7GPMpyp2iU{6n|BUib|qo2wJvjUhAauicp$#~VDy1iCagh_i((S; z@z>KGMlA=TI>iPYIhH^&$^BZld%9X}-J6A@@Ck}pxnm=}>0L`_lCg}w$HT$GE)~vU@H@YZD+6|dH>=(1c zGsUf`f1;X!Gug8r82$cTn#!dNlHefj(9;Gm_e2MQ{v_)>Tp~HxHSlfY zBBKaBNJ?Ig8Rt6wHEWeSNr>V6dxX2&)5*`SEc6~=80owysIsK{jszUMV3qPPA? zre*d5ZI%(vGgmd+2A(jZxUJOL&JXhBv>J2mmod1EN3_K6?Pq4y4>YqMPUiW?-%M3f z{{FLA?9kzS&4}r|I+si{T^A(?`$u3xhHYD8r@!AQPp%JPX>2hg1oxRcfyQSA1#5~CMl&) zn17jc>)OA~bNOO{7h2G_8Xf4Vblx~#KVu%gMCZ@E`3-0{*S`Slh=jLl_k)hP4^}SJ zs5>3`Pjmj6Zwot;Sbt1&<=%&gS2>UK_6+bQ6Z^}^Wzi_D>dO`nD| zJ?bpwK8(o+Z4yeaWgPc85TD{>2j&+Vc3x}9X6KZ@7id|yv0%{;X;Bqgc76cN7PS8y zeb|;YS^?3O)oKiT5B*ZOyvQWfBP|_5+P((mB*6Ee61CCO;c8F&(Z7R^Zk#lK#~|!y z7f(Q2ghS!;q2|jZbP`F{92(y*@J&x)0ibh1DT6ca2IRE*eB>a~;urrp7A`oKnQ z9Cr>}qnWQ)9l4PkLL_`(vBdGa#o>>41IkyVsPQg(eyfzh37E5Sk)o`;0lC(0WCSF2 zFwEj%I(2W#Zz|qnPIyAJ4bva|P`Bt!omZikOeRncmlo-o9?$!HwR8E)LII@?oB$Jk z?`MB`PP9^HijimB*a7xh6|`P}EyxJ(AiMtUsCeWD)a{;7987zqiCXD=D6ayKeaz~J z+#`f-2=&a2=@X;C*HP;G2^Ccmru<>xw};xXh1nfDH){vcGokYVqngS2aAxT=uAgJ- ziH!}{GGU&;%fFF|UvJ$t+}i4)nVs7WiI?MK2^HLwh%pad6j0i~|NNLq{5o9Yg{t8{!X+-TN zG@E8j)(Gx13Xb1Ws(TWs*`q@pKPcPvde!b0i>h#X{_~0vMp1%s)oHygsrtBU6mAMms_~F9G*NM7u(Hbyx}n+@u4E9k1~9CgEe> zr^Qt^!WFDXYlzuPpIic&dE+L(qM&J}(p6t!+n%tI0==?jFl6h;Ht!*n6dYF4lrrFW zudEo*I65o?^^EPYh|uQYH#RqyF*1tj#k1>>Yki*Q#AlZ+>p7MKfK^%F`GYz0@Btg=#p5k4ZA+-QKY*W@ge9o_N6E~7sP((LnRjz9F z)-m4{%_igX&OenikiuM&ul&7aj50-kqNSw`xWx%fH-RNo!H@r$2bXPF5;iz&rZ}zs0$_ zHxrDOxw!N$9NJ_zt^tll3OTv>9M>B(ewB_?dIU-?d;Z$7wq1e|12D^-@)Y*#5iI>z zw**NrS-IBzW#4?I0pY^ZFfWVa(q#02`KRxtNPx=;$wfN<66KnA3z+2>Q(OwR*`Pn4 z5Rf%*v(oIfLWqgH=fVt%?;othY;UE_S-=$#Zj~!xi&p`>uWvJb3H=h^odI?ZS*)%1 z!~X0aL9_-{tv=>Y;dOG9?QryrK6dxtw!Lc?rm8TLGc{uidUVfZXDO_!9%e{5j;e~y z>XAywD6mL%j;1WtVrnwNTfxSeOA9@Iu@qGI;;QX2os|H($mF|^@4B(E?dd$vrZ%;` z6LWX-Xx^JrX2N7_6X#H9_G+t#`Q8J>)9CQ) z=LvW|XtiZNHj^x1S2OS^HuM1xej#6<_?9uxFpECBIxBf9-9`)an{Os6fLI0i86~lo z(k7%nv3!ff2DxNEt+20pHzf{P0jlZ4f|zt+R*z)wyph%lg`o`cP5b-jdT9HNuD+2Y z3!n# zJKc20p4HY5P_d}HZy@JEn3 z)&joC#1uCy&Su#>bks;{1jXA-OG)lFEDouv$ff4bV*s$aT9Xu`?ctwuiOYxgJPbZ$ zD0e=BMDB#kDI}bq;qYAu1Y@=En|b4nMP7EvRh1V@e`d!~00tr_J(XGdLHgXr?MN0J zOC0XE(GHK@oaL|fgDuOSlXoRua?0wI2;Kq-{PMtlx$fmd6=D=!|L%Qjav!#+Y28$s>m0$>=lLD6bQN zf*9a@S!C1alU}d;&&t&s4E5AySp>M$ov0UTR)JOCq{GXqu8I5&VD_dF;h>Y9P(qqY z%9c(wx9j|iC6u@*iVF2;Ru>sV$1YCABO1xf@6$WVv?=M``<`IMnU98wfk!GssPbOr z-Y9W~O^)VJXCMez6W7gWjnB6Z*l7RGw#i-HSvG=L69(=FCb5eq=CtI;6$WL;7_LPx zEBaiXuqFJEg>TYq8;L4evEuH&&q)2!8pgtpzLS(ycmc=4G~Dfg`%MymDSIn&+|`*O z*p~>!CB_f_1?=94arcj9U@&y)=ES$gD~Q~pq-A83p3XsSIDi^w+2BGlY|)m(=|OVH z>zdsPAKwSoEpe4nMwB^G33-3QI0I(RY6ORe`o8$JH6!v+w`af>{xxNVGpA0VqfIM+ z?iK}JHv#DhW|xpkG?r0%Qm-+^Z84?NyV#O(%Tr_OT#d9ZBb$H)XG}(!%Q`-+s`e|K zhJHI;3k`r%()z?!)+vP?ya0&&;T7IEgOu~X6zHQt+ZRZxUHFREb?<|UGdX26`3GoJ z68Su&xJhJjW!xC#;;S=L6ZEWt=W@c8553yJ*68!w>RdHQbhufuQukrF}dckOlsYW7PS4vaViA1$i}@p%U8I^NGXD< zA*i-fMy4L!u|ZP%;Jp;el=1pI>Ko?l=kDIXiW?QE&y!O)BcON{PQ}4cyfss%LR=MJ zZ2C}`)z94xE3CI5lb?z9n#CZTX=IQdUUpW5hs+qUp+k+cu!Y>~Pym4lajoR??6wx0RXuiYFYM z{6%k*q@{9tQ1IbqQLd|8@f!PhP5JH*HIWg0ygHu2FLlWOzXB{(d;OB?;tpJ$}Qevd3PZT@1rK8QSFgEKv^C| zNXYc{MtP#nj2GIgDxij0FjQ6t#1AlD@0T&@N`zz%6pSUq))T(Lk1Y2+XKt-yTVwZLu5fsp01ttCFdPjCD=jyPr!TC%(@sK!<( z!l9ZafPE>>U2!T=CZ)kKJ#mMm(5lee!B>tg&}{dO$tg^3KLdyy6J$Qfi|M#4Jv2kzoKJKl$ZV7iP-r~r#oUP5;G3A*475%*Xk^gqMxw^y6~@ z4(PmU7yZ9RWWosmbul9SoK?tjm7!Q}(UB5L*h3{+x*u@Gh|&F)%B(G$Etb~C|GWg%4s>9SX!-xN&yjuPl7DL&4axXl n;jR9E1Iquufy-*bN!SGz;JZf6@S1a*_=QJ0#@gkY&m;a1KZgpO literal 0 HcmV?d00001 diff --git a/images/pipeline/create/inline-editor.png b/images/pipeline/create/inline-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..94c821666d816e1bc1fc8e0b28b4b0cf25f6f87d GIT binary patch literal 80488 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 =e2ov@F`%ih4Fl^<4gv4TxKa{X{ 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 CH7|_- literal 0 HcmV?d00001 diff --git a/images/pipeline/create/pipeline-from-internal-repo.png b/images/pipeline/create/pipeline-from-internal-repo.png new file mode 100644 index 0000000000000000000000000000000000000000..29d47914f246e5403306042f9cc9f438c49ebb93 GIT binary patch literal 80034 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ðB;vrv3$&mLjplNW&69JcM_AXZs+# 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

&AK)mO94P8kGB#k0I;Tm;XCB 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 literal 0 HcmV?d00001 diff --git a/images/pipeline/create/pipelines-from-repository.png b/images/pipeline/create/pipelines-from-repository.png new file mode 100644 index 0000000000000000000000000000000000000000..b1205e539b671af9770ba6b013079218bc31d673 GIT binary patch literal 28746 zcmce-Wl)?=*R~76f(Hn0!GpV72<{0^aCetMhv4qPEqDm-GPpaz-5q9dXMoLpzfY?6 z_f)-A`}?z-q8M6Nua>K?^XLixq9l!uLWBYX1A{IrBcTEV1NQ+223Gbh;%kh_d)evN zKZwTi(h@K)|NQ)HD^7fkL3WhUc7cIG#rfwK7A8HD;58D-RaQ|FX$u(}ljLpSFF!IE zm=7?r5@Ko|OW;*sT{W}km-7?~IF9r{l)SjlC0ZMHzY3ceHLTZMO-k&n%l8~qLF^2? z%+oc*-15^aWn-@L)%C<9%e`DHxVGx;Yc%w!Vn^@Z41d7rM&s)c{Uot#-gJ)WBT9}* z-j~Ta&%f_d;gWU9zuz)Gl?~{L%ot-@Tb?b9ii!Bm-q1T zDq7hd`p99gVX)pKo+fXn)$}NU=HINEQP}VPkFs+A6nqUozWv+v^XLnDc z|5Hne+L4hgC4C{dcN^M@m%!xh$a}wiT1oe6hsx#5FZK`3%{&lxtP;H;X*q0J*>M{3 z6l!Lq#Hx=$l$3e!I~QrUo5mLx7j^Rz1@6@3``JD}1f;tbVpTeFOel5@QTR~`!@_1h za2KI!ST7;-ID~KBC_$P^H8COlSS6c_(kS$W)Z_@;LOyJ`@*>Vm^aTY4hC|JK$g&jl zeG)q4ZvEI;@y7zN{9|3}Ip?As()Y)Z>{*qq{;?Oc9RtK#potnc^@kyeDDXt<-izTt z8Cg;)kY)!PcP;U(EZp`RR}gKA4SjVjABPiK5=ro5Tl*#yG3 z=xIsIJ-2eyEU-PZ(6R@Yldnk!maZ`s;BY!H)ON(s&^PkuxZ{3 zi`T;`2?11j?HDrT#%uz|8uc9JYnN?!SSEJ&KBMk7zvIHVAWOee>P&9`sa4b(wfZ{n2X;`*z z#bCEX8Iv>VAKsuJ^HSEC;THwh6)LW(3^Tu9x|E%3;PW!>X$B zSRD|`+3KqcMf^0=;qhc@<)-0)OZ585yRt58O7S~)wCZ)c}bTy{M z5@lL9g+)dzd3>&Ek%kyee0Hg6fF%m`F?QCIi`~rkj7Mue&6CKlo3Ift zUpT`{Os1X&oS@(Za}~=rYu@^!8E|Di62UYd_DV~hO@fOF5}U#tii5r+_Heekz57&{ z7&n!G>8v6{&;Qt2{PBLUOXW_A36Q9~sZ*(N_n5)wakfQA$FHTr)Ys0a?qqr#s|C8= z(-7yzJy;5X&3|+%?HZn36|LbpQq@-&G z0)+3o1cHsywZ`M_4PapW{e-)qf&TeDN@7ltU6dwIh{~Kg_9W6ae-NsDK{fOX!=_#< zYt~p_=vN9mD>%nJ>I`7){u6UY&6Lo0^5>a|BHXOgts0QqPgD)yvoCq%_8d+Yg5Zgj zj&pM`{sD9ADhqQDO$xjVi9Cj#k>T$oaG_LhMxrhArjnwRCF10?UMimIn)a|^CX9!$j0 zV14|d0W-x<_U$ijYYocVyN&um473z4jozZL&%B$E+0+-_Bi6FVXX$62hp+Yg>PfBX zVZIPTkte9{(beGFyqYC;BMt9%6az(xQLUm|M^KE(du3-ykxJZ*Oc{+!vK4&1jh)0s z#Jfi%?1h34gvhq!pSN)UmufrKz-;W#GU&0=W{GhsiI^yBrb((7@G1#RO^+ZG{#1$K z=J-Q;JcVbwb6(gJktUFVfTb|qKmY=coY?QdmLz4-Z-cV(Y~*Mc6-A%h4ks&l^Mjnz+M2u=Z`p8a`d0FIgq_>vwZoXi{{{3GM9j^-czajABgg zhq7I*u8=CFC2?#nP1V+ON3S{YYtQbf}Q8$%YR`4YUA=OTlP{PN4x@0?-&C z=ZmA{v$;=zmb$}ljzUI-o2Q^fp9iTEjHBTu#7}GF3eU7t&AU8~lz2tsqgKQN!cLDK z%(*&!cA`V9S(#zt{nyJ@C$L4LFln?$9<$Cz``@OB^mMz1T_< z;-D#A172Uh*rb#9v^bH5y2!%AJ+7j6w%uNBJ(4$^jjzPs8E$smY4*u6h3K$dpZMUB z=rFS$@VVsi&8Iu#8#BFcx=>96r@R5j?g)%@Q%b4^vB7r_A;P1+{&Zmv0uiVkM>`Ek zggM=IX~ON6%ibbvA-tLcIk9c!TDEdaArbu**v1yO#m6QFF5P$|Gufnv3)NKHyrxMH z&6khD*|Vwxe>yBQ1>D;rjaYppZIcrnJQx}6)hoyk%gELfjpP$P@COVCxEGiVJddtv zo-Z^T!34qv);^Z5JZwpf4(m#7HdHE6yF2k=UV-K2vsu+YBHs_>JZQ*Ye2ruJAz~{u zkkH#Dj5I+<9t;>9PD)hWf2S)Hm0+71)N*WR7MVDN5Qh!%OyxT`Al^WtO3efr z0XkW7KOSPpMisTf^)9LC=WWpnn?~1ftH<~Hzw0=dxa#<=jFXt>E~fSWq=;Rc44&Jm z;b)1VQqMkx5_T@bY^Vg!2hA7e>gavQS@9WUKQ+F$vh;9K*1rU?!8-FIus62h?~t2p zcBwf!^`Oh#+2OBe4$?DBv|%@{FxKf78-Gna8UrJCQ|~ch(z&nqUXO#R&qt`P$5Yimo4LKJ zY$qRA)=Eg9nV)_gZ*>nP;- zD{eIDUcvPNxeBaKYjSc61@sz6JAt7kwr>eW^2P)g9#&mHCs4i3xl-TEx^(4HAR3Zi zCgOCTG;eTNAI+;CTjX&Qs=ZD6@um=m+l`vFe0;ZE6YqSr=v0e~J+3#lpVR!N-B>m; zdco5Hdsj4B@)%I{1k!vPm7{zIUO>euT_K><5MSTyYZ(MbexPiJH4^W({0ws|O!C=Y z0lqYmRe178o84|-vEgzL@2B-c`Ng_JK|Dopq>eEM9ZHI$agPvXQ>^Ceaj}s+CQsJ( z-0qhpn1Rl8%Zq0Mj1k1I$jc1KXuPe337K**S5-A$@81;zl( zqlY7O+-72FS8g{oG@>p-`!Q=RCtk~GPxRj4@~75>t+Qn;64zMr`tU)rmJD|1Q!Y&Q z6tb$YUcT}<*xQWyPAC~YTutHvu`gmp-B-yEJ`VIq)+;4{ zhW)uw(|9aIa!x+B##Mp$mt)tr>u;aO))+dD7siKX(3H$cwmavP?_EK-LIRV*Fe=!i z3;sF+2&%0)-^Z+XT{k--D_89_hL^{s0%m%$^0y+9ar1f4>nnwK(`M#@G z3pK)UXw9|)j;Y(@KC3&D_;7J){S%(*8LYg#v6(9hdAANmo3dy2gszjSsk$7sQ;RNN!O=io%JP;2nK-vmOSC>&82mOMk+Cz~8|nkaF9ytT12#F$JzS@YU) zg$pOD+Z~bYyA$zmz_x_5r*M*zUU{|GHDqD(^_JFr1uN_}%|kyn!qlFq?${MjP4{s= zbYyLM)ZLcT0LqKIF8U<;yrZc!4mLMD+ChdgZrLOQs}pX`6)5f+;^922!J}t0)8Buz^MZRATb1a@Ylcf@;|ZEg%nMT_ zSNdesk%VZZn(Ah-`M`^5vK2&DhVhdAYli}DB4Q)|BX3Aq>SryZ`IYZg;X=z#_O!mF zBef9LqoxFcu2vahBbR*+sBX%ys_;=FP%P4(uf)zT%;rkR=IBR7qq(^5(*C_C0y3VQ z!Bm2TxAa64@wm8RYL}a3e4=-OsbT2UyeA`9CkWDFi9pP0lV|Go2ZroT9F`SKGkcv& z=dHy0begX`-R9%QuCd)_+=Sh|WC(!YutZlGE{AZGzKekWnPY7b1*@ATx(kjLOmUPe)}H_mT_!RSa_tLjr#pO@1Wd9zJ5hd zhb)LqVxK*Uow{IdrJ~5r;Prqn!Mn&v+7?R2LpRhK&yz3R?DVq~9nRI33pMza_q6P5 zK4?Vll$5_F-89`;ZQd9^+Tl(Y`AYReD%rN1mz{3zdksQGM-|)0Qm>8_x^oCsw{$9% zGV7{*`T$MMgdVuc4;rUQ>EDe?)83uiu85h9{%g3&AvA{gLK{+Nm_w(9AQKl^@L3ErZi%+6fAX|}- z$T`#<&sQ`%HXFr49QW8a?eVF%`AMr^JNL)6!xyQQ-;F@NMv?u2P+vmNqh_ebt!jA;i zp>?QZU#$b7Lzh6xcP*xca&x@)2Y~Lxx_xnb4tlZIpVX+Cfnh5~?l`(e#K$e7B)LiX z90j|BFH^y_U143gRpz=g!ejkbrMPUyOlvwl+^I&aXhngg{ts*ID_ekeout?f@`_ac z7Ev;t)A8UOz*ac#TERrjgs11OWQu-8S5(Hs+mONg(Z~klGxW~l1$N&L90~a_HpOQf zOQ;oU+Qeyt8}YlQAp_X_ndo;&j?>K(LIUh3!D7LF#AjEW>cSx^%0~FtzDlG{$ zedKr|F^f1VO^!pZbzBj(wQeIGWrzyT@efED2p#(S$lEk;5R3 z>I&ZXoE#^=v@V>+_1e7t%z%*PlYP~V-_-0qDtdVFnD$a(YCM0gKGo&Hj5Qlgy;pc* z2$B?klbMs<9y^O=P)os+U4V1AV{R6&e)6>4o!CT7P_x4Jt~&^q9IsXQ0J}NGq4G3x zqZCIt)fsq(G!&0zTMPRtNf9|sQo-`P!{Ux7dm`ei|L1)2ThAZ;2M%cE9iH#w+5OuV z?q*9iH#j0BF4j%l>cf;nw~9U!)v9ZIGw$!tCi1#3Wu>!nKWaq!wijDHUDA1*V-Kfq z*=l zG%m!x@A58tbb|8^jRv{0d7a2xUyIxcAzxyGdg`#<%Y2*>1A%PK~qvj1oJL`mBTa9&N3?$?Xy{nt#2meYdQkZ?g(c=-SwP zoa*e0b+T)tIHjJXTYY=ZqF}hvid=#;GST$sPhmi#KSRw*z|4BH*5Iz(Cyu*Q3j;NQ z`=$hFv6ewc))4*u?=HEk&zsS#oPnf?+o;2~r>9`NeeBC?#Dhnp zYC4$5SA}`t9Y=iObPr3*TjjmdGj<7yGTP?#GZnx2+`EP({2WABf3AI-hNsNFxT*+) z3lKswj$k7q7iN>YfGS?BA{^9ev>|{_62dC`by)YMW=q5OI*_4nn%R_cTKegAEwHkS znj+vVgOWNrhD%w;Mq;&_N1D)365inh@0gSPuFD4#F#!rEC-~?btYR_21;XA8TK2e! zk4k|D*M}gVmLlRxG?W4n4V4>*{qHus-EyrR#=B=XPnotj3RE#z&93P5c4WCJ24g}L zJP^S&GiCVqx=pvo15~dYkKR^rEw69(!N}5Kd|Afx`%sYE9^O3Kjotd#q%9RBheQ@L zzg7&>9EwWCFXT(V-v00&>9hA#el#!Q2)n!edTiUwDFVk{T34^qx1oqzk;0J`r4=3NUNpyPu7vNY8Pym*TW30Qjb&hLO%MC*?A z=0)XCWrgbF2lvy+(&TzO;5w7}%?PFOlv>_YR%$ks^PG<8owES}B!jn;nKvFi{*lGg z+==ptYOjwvAv;^iXGTar{e@HUA)2xb`5jwOwJ*9v8{v5CFOP)jY1uXWzO9sgHaBr( zMl8O}Y9qwFwR8yy@I6QIcx>^#Z~oyim=(838XF6@^NeD@lGfRTav^RdwdyM-&O)na z*D5&Aj{=RH?2V|Oq(p1t>w5Hg6Uxbhmbd0pVyS~|Lg_*8!>$xfQE3VO?JPF;6Bb>D znwB>EE)~6(Hs#5)x!MXq{sc|b7WQMWK5X7Gr@c1Jkw4VINjL7^oNE(wSQ;b1bZH~~a&C&E7~&Yq#@i?eO7 zlME<=_Bo9Y-aTOYMa*l^229r1v2Iu|c8(}x6u*R}Xc?W39kX8L7d^|VQgy&Y-1b(S z;(s}6n873)fb#ZF6-UQ!FZ-G5xxV2!wMWa~iX?nuNcJauL%!A4tV)Q#7wYzcC}IGm zN1eCb|HYmPtK2>m^u>gJ-8(2nx~?k~ZwRdXG7>VVr==H2sMYO}rD62c)Hf@qaNc!r z13$<7{3AG0)NC`|5`#F9@CGXAbM?6qb<45K=bzZESgka}a%Z$chB6-)wr~Y}QK|Y? zR}WXv9I54g!br z^UybHJ=+85=zi|}n)Tvlj7h<*y)o2#yTaDX@-62QPmeHX_%71zD+J(S_7ObagrkZ8 zM&|1k!}=_(k)KY7YPUMjMNS`KW4n^ufY#NvK3yDr`)AT_G=&I@-lGp>`*!e&Jb~9^ zq@{(owa5u~J%AU)G56#wPS9kJUUtJX15$qe=A@5{U@e}!!2FT*{0YAwwe#oCf4)c` zG_jKIITsi61AR<_w%69$NN?9fXV{Hbh+|muQ~3LXV;q?{1xYXl9AcD1-5rBsya&#o zn;uDX^#u4@g4Rw6ZpULWT*iZsv7Vk?VshI+d;+cq8wXR~zf4w$OG%KF`AIOOW3~tO zTlfTo&I_r^ElGhcP%SP$eCdNWDiXgJ*Zup$;1S4E|2S&H&Bo)cpuiQdr+R+VF*POH z@d|k2Jy4QYVilvl-NM(h^3uL-Xtg;U?%uit3e3MPos1zVZYXcPdv7~(>man*#9J4c zFP`#6`ZRZff9+*bR}HAW`~?V>YrLHOA|3iilXQ|sY4zA+e+?ssWy1ILieb$G z%}*A}<4d1D4)Cw7d;X4^$XY(-?i8k^<7kwzIrvVB}!+PPhEeO zncIF=RW#zIZ90w0YVoafD26g$y8_6gJ0->`mz1O}=ds=K-V9QCaUAKw&S*nOfO4kh!&_SPr6#RT_k$BL+3C6{s^^HzHtrmT?s2^e_3ct^Ul>J?q? z`>L4=%SeDEZL^)3pU{>?%rU)D_3tyoA*{w@$E}Jk_?>UF+2M>DAJHi1B^Xa)V-G*bCaYja zlAzM>C&bi*L^frdoi|SnA${W2zpu%-$$w?D+3>w1rR=DC3ar=HEz!hjsREvF_C!_c z@FfdE_C7q{QPae$7-J^{_Nk12a=Q)CyiQ-imB+#=;jdU^(W0cB4<%uG-Ie-)AD;5a z>EFj6f%t#E#;05_{E-irl&D|;ykZ1)Z50{0YD4((Zdi}Pl=)rwb`{afjkeh=1n z?z|GtVnc9f-)AKyj6N4E006L}D3YphA}92k>mNd{me?(}`%0wiXVFpoU;qCfvi%Ps zr}^+NFsJ+r$p7W(ueI`fp(clgsWTD#|Gf(kHYll(Gye6R1Pjg+cFVt&=(7I>?*CQ% zFJJ$Q?(^VZ4S5a!h2Q_St`az-C~Ecfy+pyVuHLb6<39bnfAD#cfQC+mxY55PKb}!c zuj+p)`HzYJu=#(&-!}f5@Lz5GP5y5a{ucj_1O6ue>#qNofBqK#Tl;?+|G(_u|5p3| z;{E@BYyaD||8m^l!TD?Z-{k*t+<(uUzsdjYxWC2!bMxYF?anl_p<51R9?hZ2N@nf_2ru!f9?g~Hh9>)?10H}- z(n^0$Ew&cLLj%!EBirbsnJ+3ySr3{iM#?y zXiQ;3njPy(an=F%f!ImK`D5Lid1@6qmQ$R#+C>t1Wz)%q%6nC{H`1_t<0&0vbYt0l z$#6&uetkUG*369|wHAq1BE1a``y6Id#u$qX-#)$3$-{_G%j#dN*O5_?sAQa5B|n?m z@vE_lO;Z51{S={rY>LXS?G*A)YBB0lvU5sv*!CiUoxIYIHj+e7c9#}n@usld&z=H? zf+nJ9uYao-a{Ln#sO zZS8Eo)1z7DlI9}~@9=EE#kyGIG|C`JjW0WI%vl%3i#(|eBt-{Da9gGqLiCNw7aMq@=X|{;btl_m zsB5gx@ut3qkcM&sO+P+MG0KAGFJ>czQ$GhXoWl=}vW73>W)=x}?8bUGTSG%REyfLf zV0EM@1vQxrH~XnM06wGmAP`4x;$}o;==FlVhObbly3-=G#Ta?HyJ)&}POZ3Rsep)u zI|5*!*S%)jIUBj$O;+G%38ODnRYY6EX-%5po?5*b@l`ro_Zq%{;MPlD$WfXV$l*7p zQW|Y19UEB5+6W-)?i$wws#cCW+wcX_l_R0&KQ0OTfhp{%#<0)ZWf z`0|`@mfp>jvx>*i7++(2c|$p`@kZq*tk^XyW2Qi&Jcg%jv#F01BI=yPnR^i{C(`v+ ze^7aAisfGF7=mbyVbSe@l2)7XJh#=Or}sQr-V{^8W*4&vtk7yRT@O)GJwHt}Dt*IB zyWWs+RkZTxA;}1UYOs-$)7y2&UHnzrae3ffTW$_y9Xl*A>a6@KPj>7`XX4|~+t#mv zqlp&mVR2L{CX&Vm z3({*Oy{U)d)s=ev538~Ti_vx9s}C=yY5sLA?sHXOgOLkd;>E--Y#Kd`KXIO7}LezaB|G@410bsAa8)F874y zr>!X3l_k=U-u7+Xi1Ce4;a7d+h%xnI^E~Ht<@%ussMOD5sszriHT0qSIeb8`Vb-v< zwa8Y5NOM<)452168X{%X8xH`j_Cvj;uKaObw3FVeHI0uqM9-?yVI)n`wvkwuEnd@` zARPnV3oV`>J#xh&63ff7uquiS$J!t)`$zoHEOD2u2pM_7EAv5hN(&w{6ppQ7?Vd>Y z^nU6L%(s|j>9+`bSg-{zq+E*3_gH48^Up!>Gfw^@$O}j0lw;#>e3-lawt1~1k+k1YK z$}T9DH#2wQ*nCDa@Tm$gu$CM!X7m>E@K3=jqvD}J2bCgKxTAIqFd6j|+pudE$#|1Q z(kh#HW|CII__gXXL)%S|9XjxX3oXefjD}}upmgI34U-Zs4sgjq1R~xhusR$pOeZO3 z(^^gJu%%t~hN~A z@Uv?R>8~%I>b5BbH$t#OuRHZ`y{|rLs%O;HqaCvM2G%o4+<Nbg6?Tncsue$$7hO`Ko=peruq@PtTlrPZwJ@Dce*k3-;Y@;ml(r8~HF} z3!;t357Qz9{-WQn2|_u9tn?Vk{0PoZi6rD}v%IB*hlKs5Y{MDTIOqe`aoWv%p`V@& z4EyBm7S0_MGG_1%;1;&gr9j6N5PBkGy=D1jS`x47dAQBj{;eTPRQV{x;nX7a;0e|*qa|1&HU=&2 z0gW^=S$&R6XV)Z=sIQ1x&;xyA_f`sjrh2BnmBSsmBmLoQE0fNu%^Ty=T0E=lk5kTA zr4ypPH(TbTpy#Vb+(%B8j54#zs6iJ!KFd1)ZJ}X-1ADOnoC6(DaimzJm?0l*nzHey zVGr4L;YmPiYB=m!h25v+Z*++2o4|xK*dLpu$sx})D75~KV^$~Iu*wY*F)RLtvV9cY zVQ}3)tL5*a+BaP41)}EWhaI{L7xjIfmLzZ40LZiIpOv8QB;8;C)LFu#CWpD!;hbSi z&xu*S>)1Xt8z&__uV)+R1IDfhY?G?r-uNxn$k{^v>+PKuyqW&72Z?^0rm?c z)wRWU*IaQ1UAx&L-6_)cyG3}}TwEUdf1*pJs*2CORhELu3u)is)CXd~8r|u~KxD(r zV-Xx7gHKd}sKoE#+Qnc~`TPRtzquaSH`t!`#n}T1qJd_vFD0G|tJ#}b_WLh9@Ih0n zyaDTpOw<|WU&8yRcL0lT&V_RyS&+CEtZZvLvfnoBqJDJ-Fp-BGZw*h+s}t zp9Rd!lpvMsnS=>z&Pn2j^lwa#KKx{S(SBqWl^8e&^~DG?$0(xGCYq*o=>)=kp!jWg zPnLD(!d6g(CjzjY#`W8}qcOsib)`Ds=mU)|yobQURqQk5lpZ4h;A|AL$~K%%XZLAn zV_VP0EhS%9eQDwi%3Ni7J9#4It8CNz>gz4s8*1?YbWJy5U0-kZ%|ie8yS3wFkFUem zBPS}#=hxm0b<5MpDZRm`)!VOJA!u|JXv1b)OHNtEP-|@+u9vSEMzofEqq2gI2qn6o zI-RR%eYc?=PKP7adQ8006kRvHNHR9M_5S-FEbIx4qk3lq;;|n-z;}1WzP&7;&%E8Em^EA}bDwq2lu`XO^t~HS}2A(|w zuQ^um3A%TtTeC#?2K$|E=GDk$_6eqXOCh;TSQ3{!@?P`}j4YTpTpkbCg9-1@p7-hk zP{Y6kd$G~Ybugt#j5jf9k&Se0QJ^Q@3(2W(YrfopaWHU0p!_=oOEMy<<0UmZMvoQm z`g4Y2(qEre+oIg2wrrn%N83e~BI(0+1)-4)$Ngax`m!(^7(z?sE>E=R-U)z7TqjnH z+w68ncqE?MzRdCYK(Dznd#%32&JBMd5w?i^6q@*EZ=}!z*ToYl6Sg0#?+KR9 z=F?8G-`~@$OP*}Z*HIhKvlyP9NEBrqQ>t#e#F&6}ADNHyZyX10yMPGzzMd&&oq`@8 zaI$%Dcs;4o7Oe`jbFZ68Pi6zz^S$4%LPTy!HS<{;_3E>*I^iZ_4fj#y?}RBr6rDDX zc9n0js62ceH}x96Y11)!t{8;0=*)8HW|bS%n~CCiKS9)YU$^HywEp7-IekBh0E4k( ztvaS3+W8afS?=!Zrh?wUrsN|D^h)Iro-9iUQIEbik#{~0#ZN6nY_#ug`n+ z-jgeOj_R%)?T1;0NCQq(>~|dx*<7}k-Kd;a78gyE`{oaNxo}ONN4PzvD)kH=>PM)! z&5-hWA;$A1>soF#bdBD#D-p(xOY$w+U+wVA$!KvZz6(>~MwV-B(&!W4Pnw-wx)R#< z)V#=>cbqeKqyye1@}YrQ9ezLM;LvfGdH2UL zOU$QiHynN~HRx3fd`&z~tY&-yr7sYhPug-NJ_}WNKsp|HlkB_KM~0yOID&$uvoto zI*2Qu?l*gpbQ>=25HR5N1kGEkn^za+NEE^x}o zE7H_2h{}iH>KJn^Cx8u)dVE)RaPc?C5T-6J$U{pP)?I~0?~FHT>;uy0Lt7s?VCR2UAOK+DdJawy76510Tae&K zyeeAkT32?_-es1y)~aHoAs8JgscMQnGsRLS)IBx9h1)8}E1Bn;9j)#hPk+s#iOocA z5bAt=@{DY8%p(V%I-v4%mTL=eHu*^_+uB|c+dvbLiq`)bv-Bm8j)z%CjvuXI%@VGH45Yx!KnAHr(hch-lnOw_xb--AM4(r7fu>HB)nl1j*5+f0KL z1sE(TGJ2p!hBl+G(govP8DPHcUU#GNhBz^iJid(tOSN zv7>_*O^eJDWreP=tm12>OR%XB{vl6&aMFY z>P6uWUPeDXUv@WAXUv})ebr>5i+wWQ4>d?uFuX#+)P*dXg1k25&WlOM?RB{4!c~^C zLRD?Vd@s<Zlu-Jwxr}S+d4v=gC>;Q5tq;Pfv&1K4Xkaau2G`Q2$T8;N}hi8#W@pI!MAF!xiu zRX?%rAvPA(Qe@~!<1Ct8Zj9@ARqvg|%yQB0Sv&UijO1YWKKIYu>gQ=z!?Lvp7M*Q% z#&F$MC1zUEF7y6y;w=8N-pEnRPDPrN*=cJ#pzCHD4EM!qrt6+siz;M+C9 z_zu5nQ?XWa{|23>%ii?L>SRucJE|3)P8a6anDp+l{m3lCsN5*eBK&fNitkvJKV#}{ z9F4!xq|LW>MMdL%i%uPwN?NZn-sNS|YYF3(MtFS~(}KJ78IMg52Yl6!PiBAp`v$e% zpxb}b(@bLe5l5=79}cC(7i&`o)H>jd{ofxq3*o=yIkqV)X7ZpgXtNn z$rjROn$T}dQfS-RN3{IXp~z%XZ^xHuPOUHC-8V{&|BR^qkh|<}WztgSd8cd5{4@L^ z&W-Vt{JWwgV7iJ#1rIShC%MTphUVw&m$2~M{bibwSciA*hM2DC7F`8jW{ksi5mFxK zmnC;}+$Q}H_eOxPBpZJptrY1O<8iPi=${U{DJSYM4RU!XJWuEPQ zPc+W7{jFWAIk>48{>D5obSPua2=n5s${*g7QR-E1$90Q#?ZW;?Qjb6G`v1rY{#&X3 zztob|a$07;%3Mz1e@swXxGxq%3HTp25zp8&-%%LwFPoUJ|35K+@+S$23OF)EUIej< z-?lmxuerV>=0=8nynpvq`2D|~&5IQI>ia(*|DhXyjruR`zM1HXNdL93KlCFRQX&yE zB4xC%;Qt3P{4ZklUn%^*A;Evi_yvf~zdM3}&`~Skh|Io%JCDAbuGNn5AF}w;Bh&V1 zS8&tp<%anL?cGeNpJJs05Gc}Y;ryzHMl;i;K%qX6UZUZ?K7>FJ@yWH2W9fcOWMpK( zzuov9$p82rNoADFsp(5c465Ib=|v>u{lKNO%+Lf)A24Lv;r)7aeiB7TcSw>gD=bPHsAcO1pacvEUo(HtguT7HZ1xSX6=5J=GedgYvr$f-mp zrN!-7Wgk&^rHr1$Vj>|WMH;A2=IQB~S^cd#ldlV%g{5h}R2oiIoQCR^(Ui_qFFBKH z8jD$6K%lNWY|JDTwlzf;(`h*1k!nlKLGE&KVdWMOZ(d_Hy|nH{(`8Xc37}`z)A7KO zk1xq+(^Uhn|Ka-lmqYKyUQw2s{GzicmqaL}WZKIEEF{aDTxR%XK zYNrxAzv(`JRAP+=1$tg~P2a`e3tD+v`xKa49UYBtqdzr|IZ`zc3m{EXX|RUh?01`>-%Q&)$+9D7-8O&e#JH?Zp+M>>)~XZ?cVe4 z*LHepWpVW0M!ZsvuWy{I6Pqpge86u@8aPLV2qzAGKzYpd0YiPAjEeSsj)AC_O#D-!d!ET0vuC2+m066BlhrW5s~h>^qX*C#f;JRrorzvaH7@WOmnVM zaLdx*^=q$8UQLqU8$v@6{|DniCo+RHNj2B_oxV&aeH+{38(F5q`126r1>KMBwPu`8 zPYPzH3+-Q9L#g@kODRi$%l;_(`pU|AJoD@8^4)n*{KVm0(>$afs(pwwG}uVrqH;{y zxPSIM1W#nPA8%CY)v@=w5}4?erWTenh-V;j!y8*$0Tzkskp`4H!N^)ApJqe4YHjgAuqxZb1JaZ0gUy1(gvt%j$amX`FK z6*on~?;GJMI#6@3gx2HU_@)>laUj&AfFIs``s7j{HGKWVC#CnL6d}M-~X38T$p-2`=I;FaE z@zccz^$Y=aeyOOcu>v#xsMr|-ZsWd)7>3K_=3eCy8-s_cON5k^&b!!gLZN}lZYyEq zN}3Y8E%lI5WTM5AD;v*=%!Vx^E`~T2qkhC|{;VYR-JR{2q#PGo)*J!1pD{S={3&6X zLnHgIag4~X4+zGT?<7L;pQW;+O>S%@)hcuzotZp9O;|bF=VD#2n~Gx(I`4)`W5pYK zTysYkstJ3#4#!L>vxHdvQcAvg(C@sX_g7O>iLYq4*%^6osEny0hrh&f*o~EkF7U^z z{(&s6bVIlzEcE_U30I@nb=B^U+7W1?@AbR67hh|1!aSg!OtI?&-#HTEI6d!$@N2aN zU#I1;8grx0>bO8y?O{cVjIKSco(mf8bM~rzepfV6FJsca{sgH`MYI<#xF4`{MgI&~ z0qf?JUd;Hvkn+0hT$QLG7Vcx=Uh?-~S_Im_M3NJI>OjRvLBlHx-+)8{4JOCxVar>6 znmfiIQMQ}1J#rHUnMo7#tVSy5**&~X8|szFSvv5SpF?$!S#%p;mhTAzF-$jS_rz}2 zHg)_@lUsrN@WDd;n2o#m?;A`QZT zJ1IqvbuQ9wJ0wf%0a zXFjr$fyxE_Y-Uo4m7ik00Z#$<328na%ypuEPJ(`4osSe~1*dM#S+{)U|K0^S*_6PZ zm|ICDnHcGU*!ETKT!7u}9lzd|9*2)vBjm@UPOB3mkZTHsyS+Y7GQklqA2%OG2evxD z@~yNE-y>m2i>0}ofc3hiUi$Z?QHVVru|#C+rdX?Xf`&?EZCd78Ey+2QEvgvrKRD2l z?6E;SGEmzqC1c zv!f}pakJe@TA!xz^f)y!lyaKXPDV+|%>-NGC$5hD4!`9A(UH@0XDYR8jOcu5^Z2LW zeDvz#N;5@{?PIpz^6*_*$f4t_TzT$nq}oj@A{ejo`QobrkimdNU{L?asZ>*k%nD0t z-plc{UBde47)|BUrMX(E53{uP-omNGJ6adM*Kc%Mb!_Ej()HwAjmnc>%iXW@nA79~ zSEkj3YY+Sfih41NTg(ub-MOr(~u5 zR!8szSGLxPZVSYrKOEx>;2et8k@thgy8y3~=-z~$j?@3_S9F=&TK7R#HuM(5V1-fm zB{;zTu-7S#n(EvQM5fd^ zBd%snTw-Uqq~X@LXm3}|8QsUTzzWV;x%Wa$ij0>RHSgH%3~%aXeeG#LQl0LB+;0et zGY~E+;QRNB(h%yOyw*pAs1cLEhA5%P! z-g4ZzvqliVO1lQh8S>31MZPB_i=*WDwq0KhVofe1g&r?3Vj6;C$NFaG@e`{za2rSt zAI_(_sjxAo=U$%spA-A=CL-tchiE!; z9o%cc9;Ym?dU90Vμ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 X#7iMoZ9M<=4@OE%PPF{9p6~wwzCuYp literal 0 HcmV?d00001 diff --git a/images/pipeline/create/pipelines-no-repository.png b/images/pipeline/create/pipelines-no-repository.png new file mode 100644 index 0000000000000000000000000000000000000000..7b9c7e39c5cbce7a8324efc7c2063bf67d6f2289 GIT binary patch literal 32743 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 AKmY&$ literal 0 HcmV?d00001 diff --git a/images/pipeline/create/predefined-steps.png b/images/pipeline/create/predefined-steps.png new file mode 100644 index 0000000000000000000000000000000000000000..15a6939dd234e2146fbc70fd6a5d0c9176309c16 GIT binary patch literal 17642 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 l#O