From 1d941e8dc41d79b1f1a400f68e4b4888f6e19985 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 10:19:28 +0200 Subject: [PATCH 01/17] Add CI examples from classic Ported all yaml examples and go lang examples from Classic to example-catalog bucket --- _docs/example-catalog/amazon-ecs.md | 155 ++++++++++ ...n-image-from-a-different-git-repository.md | 94 ++++++ ...ld-an-image-specify-dockerfile-location.md | 74 +++++ .../build-an-image-with-build-arguments.md | 133 +++++++++ ...e-with-the-dockerfile-in-root-directory.md | 70 +++++ .../build-and-push-an-image.md | 135 +++++++++ _docs/example-catalog/call-child-pipelines.md | 108 +++++++ _docs/example-catalog/cc/c-make.md | 75 +++++ _docs/example-catalog/cc/cpp-cmake.md | 126 ++++++++ _docs/example-catalog/ci-examples/cc.md | 10 + _docs/example-catalog/ci-examples/general.md | 16 ++ .../ci-examples/general/selenium-test.md | 75 +++++ _docs/example-catalog/ci-examples/golang.md | 13 + _docs/example-catalog/ci-examples/java.md | 15 + .../ci-examples/mobile/android.md | 81 ++++++ _docs/example-catalog/ci-examples/nodejs.md | 14 + _docs/example-catalog/ci-examples/python.md | 11 + _docs/example-catalog/ci-examples/scala.md | 10 + _docs/example-catalog/codacy-testing.md | 173 +++++++++++ _docs/example-catalog/codecov-testing.md | 126 ++++++++ _docs/example-catalog/coveralls-testing.md | 218 ++++++++++++++ .../decryption-with-mozilla-sops.md | 179 ++++++++++++ _docs/example-catalog/deploy-to-heroku.md | 213 ++++++++++++++ .../deploy-to-tomcat-via-scp.md | 123 ++++++++ .../example-catalog/deploy-with-kustomize.md | 248 ++++++++++++++++ _docs/example-catalog/docker-swarm.md | 227 +++++++++++++++ _docs/example-catalog/dotnet.md | 115 ++++++++ _docs/example-catalog/elastic-beanstalk.md | 137 +++++++++ _docs/example-catalog/examples.md | 119 ++++++++ _docs/example-catalog/fan-in-fan-out.md | 206 ++++++++++++++ ...short-sha-id-and-use-it-in-a-ci-process.md | 69 +++++ _docs/example-catalog/git-checkout-custom.md | 105 +++++++ _docs/example-catalog/git-checkout.md | 204 +++++++++++++ _docs/example-catalog/gitops-secrets.md | 232 +++++++++++++++ .../golang/golang-hello-world.md | 268 ++++++++++++++++++ _docs/example-catalog/golang/goreleaser.md | 121 ++++++++ _docs/example-catalog/helm.md | 225 +++++++++++++++ .../example-catalog/import-data-to-mongodb.md | 57 ++++ .../integration-tests-with-mongo.md | 101 +++++++ .../integration-tests-with-mysql.md | 113 ++++++++ .../integration-tests-with-postgres.md | 99 +++++++ .../integration-tests-with-redis.md | 129 +++++++++ _docs/example-catalog/java/gradle.md | 208 ++++++++++++++ _docs/example-catalog/java/publish-jar.md | 117 ++++++++ _docs/example-catalog/java/spring-boot-2.md | 256 +++++++++++++++++ _docs/example-catalog/launch-composition.md | 87 ++++++ ...vice-environment-variables-using-a-file.md | 57 ++++ _docs/example-catalog/mobile.md | 9 + .../nodejs-angular2-mongodb.md | 50 ++++ _docs/example-catalog/nodejs/lets-chat.md | 119 ++++++++ _docs/example-catalog/nodejs/react.md | 174 ++++++++++++ _docs/example-catalog/nodejs/voting-app.md | 88 ++++++ _docs/example-catalog/nomad.md | 226 +++++++++++++++ _docs/example-catalog/non-git-checkout.md | 101 +++++++ _docs/example-catalog/packer-gcloud.md | 134 +++++++++ _docs/example-catalog/php.md | 132 +++++++++ .../populate-a-database-with-existing-data.md | 153 ++++++++++ _docs/example-catalog/pulumi.md | 117 ++++++++ _docs/example-catalog/python/django.md | 175 ++++++++++++ _docs/example-catalog/python/voting-app.md | 90 ++++++ _docs/example-catalog/ruby.md | 182 ++++++++++++ .../example-catalog/run-integration-tests.md | 102 +++++++ _docs/example-catalog/run-unit-tests.md | 105 +++++++ _docs/example-catalog/rust.md | 83 ++++++ .../scala/scala-hello-world.md | 185 ++++++++++++ ...-docker-container-using-http-basic-auth.md | 86 ++++++ .../sending-the-notification-to-jira.md | 88 ++++++ .../sending-the-notification-to-slack.md | 45 +++ .../shared-volumes-between-builds.md | 117 ++++++++ ...om-composition-step-for-other-yml-steps.md | 52 ++++ .../spring-boot-kafka-zookeeper.md | 198 +++++++++++++ _docs/example-catalog/terraform.md | 114 ++++++++ _docs/example-catalog/transferring-php-ftp.md | 118 ++++++++ ...r-a-k8s-deployment-from-docker-registry.md | 135 +++++++++ .../uploading-or-downloading-from-gs.md | 153 ++++++++++ .../use-kubectl-as-part-of-freestyle-step.md | 36 +++ .../vault-secrets-in-the-pipeline.md | 116 ++++++++ _docs/example-catalog/web-terminal.md | 42 +++ 78 files changed, 9272 insertions(+) create mode 100644 _docs/example-catalog/amazon-ecs.md create mode 100644 _docs/example-catalog/build-an-image-from-a-different-git-repository.md create mode 100644 _docs/example-catalog/build-an-image-specify-dockerfile-location.md create mode 100644 _docs/example-catalog/build-an-image-with-build-arguments.md create mode 100644 _docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md create mode 100644 _docs/example-catalog/build-and-push-an-image.md create mode 100644 _docs/example-catalog/call-child-pipelines.md create mode 100644 _docs/example-catalog/cc/c-make.md create mode 100644 _docs/example-catalog/cc/cpp-cmake.md create mode 100644 _docs/example-catalog/ci-examples/cc.md create mode 100644 _docs/example-catalog/ci-examples/general.md create mode 100644 _docs/example-catalog/ci-examples/general/selenium-test.md create mode 100644 _docs/example-catalog/ci-examples/golang.md create mode 100644 _docs/example-catalog/ci-examples/java.md create mode 100644 _docs/example-catalog/ci-examples/mobile/android.md create mode 100644 _docs/example-catalog/ci-examples/nodejs.md create mode 100644 _docs/example-catalog/ci-examples/python.md create mode 100644 _docs/example-catalog/ci-examples/scala.md create mode 100644 _docs/example-catalog/codacy-testing.md create mode 100644 _docs/example-catalog/codecov-testing.md create mode 100644 _docs/example-catalog/coveralls-testing.md create mode 100644 _docs/example-catalog/decryption-with-mozilla-sops.md create mode 100644 _docs/example-catalog/deploy-to-heroku.md create mode 100644 _docs/example-catalog/deploy-to-tomcat-via-scp.md create mode 100644 _docs/example-catalog/deploy-with-kustomize.md create mode 100644 _docs/example-catalog/docker-swarm.md create mode 100644 _docs/example-catalog/dotnet.md create mode 100644 _docs/example-catalog/elastic-beanstalk.md create mode 100644 _docs/example-catalog/examples.md create mode 100644 _docs/example-catalog/fan-in-fan-out.md create mode 100644 _docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md create mode 100644 _docs/example-catalog/git-checkout-custom.md create mode 100644 _docs/example-catalog/git-checkout.md create mode 100644 _docs/example-catalog/gitops-secrets.md create mode 100644 _docs/example-catalog/golang/golang-hello-world.md create mode 100644 _docs/example-catalog/golang/goreleaser.md create mode 100644 _docs/example-catalog/helm.md create mode 100644 _docs/example-catalog/import-data-to-mongodb.md create mode 100644 _docs/example-catalog/integration-tests-with-mongo.md create mode 100644 _docs/example-catalog/integration-tests-with-mysql.md create mode 100644 _docs/example-catalog/integration-tests-with-postgres.md create mode 100644 _docs/example-catalog/integration-tests-with-redis.md create mode 100644 _docs/example-catalog/java/gradle.md create mode 100644 _docs/example-catalog/java/publish-jar.md create mode 100644 _docs/example-catalog/java/spring-boot-2.md create mode 100644 _docs/example-catalog/launch-composition.md create mode 100644 _docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md create mode 100644 _docs/example-catalog/mobile.md create mode 100644 _docs/example-catalog/nodejs-angular2-mongodb.md create mode 100644 _docs/example-catalog/nodejs/lets-chat.md create mode 100644 _docs/example-catalog/nodejs/react.md create mode 100644 _docs/example-catalog/nodejs/voting-app.md create mode 100644 _docs/example-catalog/nomad.md create mode 100644 _docs/example-catalog/non-git-checkout.md create mode 100644 _docs/example-catalog/packer-gcloud.md create mode 100644 _docs/example-catalog/php.md create mode 100644 _docs/example-catalog/populate-a-database-with-existing-data.md create mode 100644 _docs/example-catalog/pulumi.md create mode 100644 _docs/example-catalog/python/django.md create mode 100644 _docs/example-catalog/python/voting-app.md create mode 100644 _docs/example-catalog/ruby.md create mode 100644 _docs/example-catalog/run-integration-tests.md create mode 100644 _docs/example-catalog/run-unit-tests.md create mode 100644 _docs/example-catalog/rust.md create mode 100644 _docs/example-catalog/scala/scala-hello-world.md create mode 100644 _docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md create mode 100644 _docs/example-catalog/sending-the-notification-to-jira.md create mode 100644 _docs/example-catalog/sending-the-notification-to-slack.md create mode 100644 _docs/example-catalog/shared-volumes-between-builds.md create mode 100644 _docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md create mode 100644 _docs/example-catalog/spring-boot-kafka-zookeeper.md create mode 100644 _docs/example-catalog/terraform.md create mode 100644 _docs/example-catalog/transferring-php-ftp.md create mode 100644 _docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md create mode 100644 _docs/example-catalog/uploading-or-downloading-from-gs.md create mode 100644 _docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md create mode 100644 _docs/example-catalog/vault-secrets-in-the-pipeline.md create mode 100644 _docs/example-catalog/web-terminal.md diff --git a/_docs/example-catalog/amazon-ecs.md b/_docs/example-catalog/amazon-ecs.md new file mode 100644 index 00000000..b4bdc8bd --- /dev/null +++ b/_docs/example-catalog/amazon-ecs.md @@ -0,0 +1,155 @@ +--- +title: "Amazon ECS/Fargate" +description: "How to use Codefresh to deploy Docker containers to ECS/Fargate" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/amazon-ecs/ + - /docs/deploy-your-containers/ + - /docs/deploy-your-containers/amazon-ecs/ +toc: true +--- +Codefresh can deploy to any ECS or Fargate cluster created in Amazon. + +{% include image.html +lightbox="true" +file="/images/examples/amazon-ecs/ecs-pipeline-deployment.png" +url="/images/examples/amazon-ecs/ecs-pipeline-deployment.png" +alt="Deploying to Amazon ECS" +caption="Deploying to Amazon ECS" +max-width="100%" +%} + +## Prerequisites + + +1. Configure an ECS (or Fargate) Cluster with at least one running instance. +1. Configure an ECS Service and Task Definition with a reference to **the image that you are going to build and push.** See [the official amazon docs](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) for more details. +1. Connect your [ECR to Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/amazon-ec2-container-registry/) so that it can be used by name in Codefresh pipelines. +1. Verify you have AWS Credentials (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`), with the following privileges: + + `JSON` +{% highlight json %} +{% raw %} +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Stmt1479146904000", + "Effect": "Allow", + "Action": [ + "ecs:DescribeServices", + "ecs:DescribeTaskDefinition", + "ecs:DescribeTasks", + "ecs:ListClusters", + "ecs:ListServices", + "ecs:ListTasks", + "ecs:RegisterTaskDefinition", + "ecs:UpdateService" + ], + "Resource": [ + "*" + ] + } + ] +} +{% endraw %} +{% endhighlight %} + + + +## Create a CI/CD pipeline for ECS/Fargate + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - "clone" + - "build" + - "deploy" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}" + revision: "${{CF_BRANCH}}" + stage: "clone" + git: github + BuildingDockerImage: + stage: "build" + title: Building Docker Image + type: build + image_name: ${{IMAGE}} + tag: '${{CF_SHORT_REVISION}}' + dockerfile: Dockerfile.multistage + Push: + title: "Pushing image to ECR" + stage: "deploy" + type: "push" + tag: '${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}' + registry: "ecr" + candidate: "${{BuildingDockerImage}}" + DeployToFargate: + stage: "deploy" + image: codefreshplugins/cf-deploy-ecs + commands: + - cfecs-update ${{REGION}} ${{ECS_CLUSTER_NAME}} ${{ECS_SERVICE_NAME}} --image-name ${{IMAGE_PREFIX}}/${{IMAGE}} --image-tag '${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}' + environment: + - AWS_ACCESS_KEY_ID=${{AWS_ACCESS_KEY_ID}} + - AWS_SECRET_ACCESS_KEY=${{AWS_SECRET_ACCESS_KEY}} + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Uses a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) to create a Docker image +1. Uses a [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) to push the docker image to ECR. The registry was previously [connected in Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) with the `ecr` identifier. +1. Runs `codefreshplugins/cf-deploy-ecs` to perform the actual deployment + + +The pipeline needs [environment variables]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) that hold all the required parameters + +{% include image.html +lightbox="true" +file="/images/examples/amazon-ecs/ecs-variables.png" +url="/images/examples/amazon-ecs/ecs-variables.png" +alt="ECS environment variables" +caption="ECS environment variables" +max-width="80%" +%} + + + + +Note that the **`--image-name`** and **`--image-tag`** pair should comprise the **full name** of the image that was pushed to the registry (including the registry name) in order to be correctly referred by the corresponding Task Definition. + + + +## Deployment Flow + +The `codefreshplugins/cf-deploy-ecs` step performs the following: + + +1. Gets the ECS service by specified `aws-region`, `ecs-cluster`, and `service-names`. +1. Creates a new revision from the current task definition of the service. If `--image-name` and `--image-tag` are provided, it replaces the image tag. +1. Runs the `update-service` command with the new task definition revision. +1. Waits for the deployment to complete. + * Deployment is successfully completed if `runningCount == desiredCount` for PRIMARY deployment - see `aws ecs describe-services` + * The `cfecs-update` command exits with a timeout error if after --timeout (default = 900s) `runningCount` does not equal `desiredCount` + * The `cfecs-update` exits with an error if --max-failed (default = 2) or more ECS tasks were stopped with error for the task definition that you are deploying. ECS continuously retries failed tasks. + +You can also find the same step in the form of a [Codefresh plugin](https://codefresh.io/steps/step/ecs-deploy). + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [External Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) + + diff --git a/_docs/example-catalog/build-an-image-from-a-different-git-repository.md b/_docs/example-catalog/build-an-image-from-a-different-git-repository.md new file mode 100644 index 00000000..736b030c --- /dev/null +++ b/_docs/example-catalog/build-an-image-from-a-different-git-repository.md @@ -0,0 +1,94 @@ +--- +title: "Build an Image from a Different Git Repository" +description: "Build microservices from other repositories" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/build-an-image-from-a-different-git-repository/ +toc: true +--- + +In most cases, your Codefresh pipeline will checkout a single Git repository. Codefresh also has great support for [Monorepos]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/#using-the-modified-files-field-to-constrain-triggers-to-specific-folderfiles) if you have placed all your applications in a single repository. + +A Codefresh pipeline is not really tied to a specific git repository, which means that by [checking out multiple git repositories]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/#cloning-multiple-repositories) you can build docker images from other unrelated repositories in a single pipeline if you wish to do so. + +## Building Docker images from other Git repositories + + +Here is a Codefresh pipeline that checks out two micro-services from two separate Git repositories. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-from-other-git-repo.png" +url="/images/examples/docker-build/build-from-other-git-repo.png" +alt="Checkout and build docker images" +caption="Checkout and build docker images" +max-width="100%" +%} + +And here is the [pipeline definition]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/). + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - 'clone phase' + - 'build phase' +steps: + checkoutApp1: + title: 'Cloning first repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: experiment1 + git: github + stage: 'clone phase' + checkoutApp2: + title: 'Cloning second repository...' + type: git-clone + repo: kostis-codefresh/trivial-go-web + revision: master + git: github + stage: 'clone phase' + myFirstDockerImage: + title: 'Building Microservice A' + type: build + dockerfile: Dockerfile + image_name: my-nodejs-image + tag: from-develop-branch + working_directory: './example_nodejs_postgres' + stage: 'build phase' + mySecondDockerImage: + title: 'Building Microservice B' + type: build + dockerfile: Dockerfile + working_directory: './trivial-go-web' + image_name: my-app-image + tag: from-master-branch + stage: 'build phase' +{% endraw %} +{% endhighlight %} + +The pipeline first checks out two different Git repositories (which themselves contain Dockerfiles). Then it creates a Docker image for each one using the respective Dockerfile. + +You can see both images in the [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images) . + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/two-docker-images.png" +url="/images/examples/docker-build/two-docker-images.png" +alt="Docker images from other Git repos" +caption="Docker images from other Git repos" +max-width="100%" +%} + + +Notice that there are no explicit push steps in the pipeline, as all successful Codefresh pipelines automatically push to the private Docker registry. + + +## What to read next + +- [Git Clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +- [Build and Push an image]({{site.baseurl}}/docs/yaml-examples/examples/build-and-push-an-image/) +- [Parallel pipelines]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) diff --git a/_docs/example-catalog/build-an-image-specify-dockerfile-location.md b/_docs/example-catalog/build-an-image-specify-dockerfile-location.md new file mode 100644 index 00000000..d8126780 --- /dev/null +++ b/_docs/example-catalog/build-an-image-specify-dockerfile-location.md @@ -0,0 +1,74 @@ +--- +title: "Build an Image - Specify Dockerfile Location" +description: "How to choose a Dockerfile to build with Codefresh pipelines" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/build-an-image-specify-dockerfile-location/ +toc: true +--- + +Sometimes you have a project where the Dockerfile is **not** in the root folder of the project. Maybe the repository has multiple projects inside (each with its own Dockerfile) or you simply want to use a different folder for the Docker context + +>The source code of the repository is located at [https://github.com/codefreshdemo/cf-example-dockerfile-other-location](https://github.com/codefreshdemo/cf-example-dockerfile-other-location). Feel free to fork it if you want to follow along. + +If you don't already have a Codefresh account, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/). + + +## Building a Dockerfile from a different folder + +By default docker uses the Dockerfile of the current folder if you run a single command like: + +``` +docker build . -t my-web-app +``` + +If your Dockerfile is in another folder then you need to specify it explicitly with: + +``` +docker build . -t my-web-app -f subfolder/Dockerfile +``` + +Codefresh supports a similar syntax as well. The `dockerfile` property of the [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) can accept a full path. + +Here is the full pipeline: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-dockerfile-other-location' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: docker/Dockerfile +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds a dockerfile found at the subfolder `docker` while still keeping as Docker context the root directory. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-spefify-dockerfile.png" +url="/images/examples/docker-build/build-spefify-dockerfile.png" +alt="Building a Docker image with specific Dockerfile" +caption="Building a Docker image with specific Dockerfile" +max-width="100%" +%} + +You could also change the Docker build context by editing the `working_directory` property. By default it is looking at the root folder of the project, but any subfolder path is also valid. + +## What to read next + +- [Pipeline Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +- [Build an Image with the Dockerfile in Root Directory]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-dockerfile-in-root-directory/) +- [Build an Image from a Different Git Repository]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-from-a-different-git-repository) +- [Build and Push an Image]({{site.baseurl}}/docs/yaml-examples/examples/build-and-push-an-image) +- [Build an Image With Build Arguments]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-with-build-arguments) \ No newline at end of file diff --git a/_docs/example-catalog/build-an-image-with-build-arguments.md b/_docs/example-catalog/build-an-image-with-build-arguments.md new file mode 100644 index 00000000..d198733a --- /dev/null +++ b/_docs/example-catalog/build-an-image-with-build-arguments.md @@ -0,0 +1,133 @@ +--- +title: "Build an Image with Build Arguments" +description: "Use docker argument in Codefresh pipelines" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/build-an-image-with-build-arguments/ +toc: true +--- + +Building a Docker image that requires build arguments is very easy with Codefresh pipelines. + +>The source code of the repository is located at [https://github.com/codefreshdemo/cf-example-build-arguments](https://github.com/codefreshdemo/cf-example-build-arguments). Feel free to fork it if you want to follow along. + +If you don't already have a Codefresh account, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/). + +## Using Docker build arguments + +The example application is a very simple NodeJS application with the following dockerfile: + +`Dockerfile` +{% highlight docker %} +{% raw %} +ARG NODE_VERSION +FROM node:$NODE_VERSION + +ARG APP_DIR + +RUN mkdir -p $APP_DIR + +WORKDIR $APP_DIR + +COPY package.json . +RUN npm install --silent +COPY . . +EXPOSE 3000 + +ENV PORT 3000 + +CMD [ "npm", "start" ] +{% endraw %} +{% endhighlight %} + +This Dockerfile expects two [build arguments](https://docs.docker.com/engine/reference/builder/#/arg): + +* `NODE_VERSION` is the version of Node image to use as base +* `APP_DIR` is the source directory to be used inside the container + +## Building a Dockerfile passing values for build arguments + +When you build an image locally on your workstation you can define build arguments with the `--build-arg` syntax: + +``` +docker build . -t my-node-app --build-arg NODE_VERSION=8 --build-arg APP_DIR=/usr/src/app +``` + +The same thing can also be achieved within a Codefresh pipeline: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-build-arguments' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: Dockerfile + build_arguments: + - NODE_VERSION=8 + - APP_DIR=/usr/src/app +{% endraw %} +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds the Dockerfile by passing the values `8` and `/usr/src/app` to the two arguments. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/docker-build-arguments.png" +url="/images/examples/docker-build/docker-build-arguments.png" +alt="Using Docker build arguments in a pipeline" +caption="Using Docker build arguments in a pipeline" +max-width="100%" +%} + +## Using Codefresh variables as build arguments + +In the previous pipeline the docker build arguments are defined in the pipeline itself, but you could also use [pipeline variables]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#creating-new-pipelines), [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) or any other standard mechanism you already have in place. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-build-arguments' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: Dockerfile + build_arguments: + - NODE_VERSION=${{NODE_VERSION_FROM_SHARED_CONFIG}} + - APP_DIR=${{APP_DIR_PIPELINE_VARIABLE}} +{% endraw %} +{% endhighlight %} + +In this case you can also use any of the built-in [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/). + + +## What to read next + +- [Pipeline Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +- [Build an Image with the Dockerfile in Root Directory]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-dockerfile-in-root-directory/) +- [Build an Image by Specifying the Dockerfile Location]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-specify-dockerfile-location) +- [Build an Image from a Different Git Repository]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-from-a-different-git-repository) +- [Build and Push an Image]({{site.baseurl}}/docs/yaml-examples/examples/build-and-push-an-image) + diff --git a/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md b/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md new file mode 100644 index 00000000..65565d21 --- /dev/null +++ b/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md @@ -0,0 +1,70 @@ +--- +title: "Build an Image with the Dockerfile in Root Directory" +description: "Get started quickly with building Docker images" +group: yaml-examples +sub_group: examples +permalink: /:collection/yaml-examples/examples/build-an-image-dockerfile-in-root-directory/ +redirect_from: + - /docs/build-an-image-dockerfile-in-root-directory/ + - /docs/deploy-to-kubernetes/get-ready-to-deploy/build-an-image/ +toc: true +--- +Building a Docker image is one of the basic operations in Codefresh pipelines. + +>The source code of the repository is located at [https://github.com/codefreshdemo/cf-yml-example-build-dockerfile-inroot](https://github.com/codefreshdemo/cf-yml-example-build-dockerfile-inroot). Feel free to fork it if you want to follow along. + +If you don't already have a Codefresh account, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/). + + +## Building a Dockerfile from the root folder + +By default docker uses the Dockerfile of the current folder if you run a single command like: + +``` +docker build . -t my-web-app +``` + +The same thing can also be achieved within a Codefresh pipeline: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-yml-example-build-dockerfile-inroot' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '${{main_clone}}' + tag: 'master' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds a dockerfile found at the root folder of the project. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-dockerfile-root.png" +url="/images/examples/docker-build/build-dockerfile-root.png" +alt="Building a Docker image with a default Dockerfile" +caption="Building a Docker image with a default Dockerfile" +max-width="100%" +%} + +You could also change the Docker build context by editing the `working_directory` property. By default it is looking at the root folder of the project, but any subfolder path is also valid. + +## What to read next + +- [Pipeline Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +- [Build an Image by Specifying the Dockerfile Location]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-specify-dockerfile-location) +- [Build an Image from a Different Git Repository]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-from-a-different-git-repository) +- [Build and Push an Image]({{site.baseurl}}/docs/yaml-examples/examples/build-and-push-an-image) +- [Build an Image With Build Arguments]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-with-build-arguments) \ No newline at end of file diff --git a/_docs/example-catalog/build-and-push-an-image.md b/_docs/example-catalog/build-and-push-an-image.md new file mode 100644 index 00000000..5c978e80 --- /dev/null +++ b/_docs/example-catalog/build-and-push-an-image.md @@ -0,0 +1,135 @@ +--- +title: "Build and Push an Image" +description: "How to build Docker images and push them to registries with Codefresh" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/build-and-push-an-image/ + - /docs/docker-registries/push-image-to-a-docker-registry/ +toc: true +--- + +Building a Docker image and then pushing it to a registry is one of the most basic scenarios for creating a Pipeline. +In this example we will use a demo Node.js application that will be packaged in a Docker image. + +>The source code of the repository is located at [https://github.com/codefreshdemo/cf-example-build-and-push](https://github.com/codefreshdemo/cf-example-build-and-push). Feel free to fork it if you want to follow along. + +If you don't already have a Codefresh account, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/). + + +## Building a Docker image and pushing to your default registry + +Building a Docker image with Codefresh is easy, and only requires a simple step. In addition, all successful pipelines in Codefresh automatically push to [your default Docker registry](https://codefresh.io/docs/docs/docker-registries/external-docker-registries/#the-default-registry) without any other configuration, as long as you have that. + +Here is the most basic pipeline that clones a repo and builds an image: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- checkout +- build +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefreshdemo/cf-example-build-and-push' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + stage: build + image_name: my-node-js-app + working_directory: {{clone}} + tag: 'master' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +## Building a Docker image and pushing it to any registry. + +You can push your image to any [Registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). First you need to connect your external registry in the integrations page. Here are the instructions for: + + * [Docker Hub]({{site.baseurl}}/docs/docker-registries/external-docker-registries/docker-hub/) + * [Google Container Registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/google-container-registry/) + * [Amazon EC2 Container Registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/amazon-ec2-container-registry/) + * [Bintray.io]({{site.baseurl}}/docs/docker-registries/external-docker-registries/bintray-io/) + * [Quay.io]({{site.baseurl}}/docs/docker-registries/external-docker-registries/quay-io/) + * [Other Registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/other-registries/) + +Once that is done, you only need to add a [push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) in your pipeline and use the registry name of your integration. + +Here is the full example: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- checkout +- build +- push +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefreshdemo/cf-example-build-and-push' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + stage: build + image_name: my-node-js-app + working_directory: {{clone}} + tag: 'master' + dockerfile: Dockerfile + push_to_my_registry: + stage: 'push' + type: push + title: Pushing to a registry + candidate: ${{build_my_app}} + tag: 'v1.0.0' + registry: dockerhub + image_name: kkapelon/my-node-js-app +{% endraw %} +{% endhighlight %} + +Here we use a specific tag - `v1.0.0` but +Codefresh has several other variables that can be used for tagging images. Common examples that you can use are `CF_BRANCH_TAG_NORMALIZED`, `CF_SHORT_REVISION` or `CF_BUILD_ID`. See the [variables page]({{site.baseurl}}/docs/codefresh-yaml/variables/) for more information. + +{% include image.html + lightbox="true" + file="/images/examples/docker-build/build-and-push-pipeline.png" + url="/images/examples/docker-build/build-and-push-pipeline.png" + alt="Pushing image to external registry" + caption="Pushing image to external registry" + max-width="100%" + %} + + +If you run the pipeline the Docker image will be pushed *both* to the private Docker regisry (by the build step) *and* the external docker registry (by the push step) + + +## More options for push + +Codefresh has several more options when it comes to pushing: + +* You can specify multiple tags to be pushed +* You can use directly ECR registries +* You can embed credentials in the push steps + +See the [push step documentation]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) for more details. + +## What to read next + +- [Pipeline Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +- [Pipeline Push step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) +- [Build an Image with the Dockerfile in Root Directory]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-dockerfile-in-root-directory/) +- [Build an Image by Specifying the Dockerfile Location]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-specify-dockerfile-location) +- [Build an Image from a Different Git Repository]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-from-a-different-git-repository) +- [Build an Image With Build Arguments]({{site.baseurl}}/docs/yaml-examples/examples/build-an-image-with-build-arguments) diff --git a/_docs/example-catalog/call-child-pipelines.md b/_docs/example-catalog/call-child-pipelines.md new file mode 100644 index 00000000..f672849a --- /dev/null +++ b/_docs/example-catalog/call-child-pipelines.md @@ -0,0 +1,108 @@ +--- +title: "Calling a CD pipeline from a CI pipeline" +description: "Learn how to call children pipelines from a parent pipeline" +group: yaml-examples +sub_group: examples +toc: true +--- + +In Codefresh you can easily create nested pipelines by calling other pipelines from within an existing pipeline. This is easily accomplished with the [codefresh-run plugin](https://codefresh.io/steps/step/codefresh-run) that allows you to launch another pipeline and optionally wait for its completion. + +{% include image.html +lightbox="true" +file="/images/examples/nested-pipelines/call-other-pipeline.png" +url="/images/examples/nested-pipelines/call-other-pipeline.png" +alt="Parent and child pipelines" +caption="Parent and child pipelines" +max-width="80%" +%} + +A very common pattern in Codefresh is to have a parent pipeline responsible for Continuous Integration (packaging code) that calls a child pipeline for Continuous Delivery (taking care of deployment). + +## The example Project + +You can see the example project at [https://github.com/codefresh-contrib/call-child-pipeline-sample-app](https://github.com/codefresh-contrib/call-child-pipeline-sample-app). The repository contains a NodeJs app as well as 3 pipelines (one parent and two children). + +## Create a pipeline that calls other pipelines + +Here is the definition of the parent pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - package + - deploy +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + git: github + stage: prepare + read_my_app_version: + title: Reading Application version + stage: prepare + image: node:latest + commands: + - export PACKAGE_VERSION=$(node -p "require('./package.json').version") + - cf_export PACKAGE_VERSION + build_my_docker_image: + title: 'Building My Docker Image' + stage: package + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: ${{PACKAGE_VERSION}} + call_qa_pipeline: + title: Deploy to QA + stage: deploy + type: codefresh-run + arguments: + PIPELINE_ID: child-pipelines/qa-pipeline + VARIABLE: + - CF_BRANCH=${{CF_BRANCH}} + - CF_REVISION=${{CF_REVISION}} + - APP_VERSION=${{PACKAGE_VERSION}} + when: + branch: + only: + - develop + call_prod_pipeline: + title: Deploy to Prod + stage: deploy + type: codefresh-run + arguments: + PIPELINE_ID: child-pipelines/prod-pipeline + VARIABLE: + - CF_BRANCH=${{CF_BRANCH}} + - CF_REVISION=${{CF_REVISION}} + - APP_VERSION=${{PACKAGE_VERSION}} + when: + branch: + only: + - /^release.*/i + + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Uses [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#exporting-environment-variables-from-a-freestyle-step) to create a variable that contains the Application version as specified in `package.json`. +1. Builds a docker image tagged with the Application version using a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +1. Optionally runs the downstream QA pipeline if the branch is named `develop`. It also passes several environment variables to the child pipeline (including the Application version) +1. Optionally runs the downstream Prod pipeline if the branch name starts with `release`. It also passes several environment variables to the child pipeline (including the Application version) + +The last two steps use [pipeline conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) to decide if they will run or 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/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Pipeline plugins](https://codefresh.io/steps/) \ No newline at end of file diff --git a/_docs/example-catalog/cc/c-make.md b/_docs/example-catalog/cc/c-make.md new file mode 100644 index 00000000..8dd0cc59 --- /dev/null +++ b/_docs/example-catalog/cc/c-make.md @@ -0,0 +1,75 @@ +--- +title: "Compile and test a C application" +description: "Using Codefresh pipelines" +group: learn-by-example +sub_group: cc +toc: true +--- + +Codefresh can work with any C/C++ application very easily as both `gcc` and `g++` are already offered in Dockerhub. There is also another example available with [C++ and cmake]({{site.baseurl}}/docs/learn-by-example/cc/cpp-cmake). + +## The example C project + +You can see the example project at [https://github.com/codefresh-contrib/c-sample-app](https://github.com/codefresh-contrib/c-sample-app). The repository contains a C starter project with a `Makefile` and several targets: + +* `make` compiles the code. +* `make test` runs unit tests +* `make clean` removes artifacts and binaries. + +There are also extra targets for `tags` and `etags`. + +## Create a CI pipeline for C applications + +Creating a CI/CD pipeline for C is very easy, because Codefresh can run any [gcc image](https://hub.docker.com/_/gcc/) that you wish. Gcc docker images already contain the `make` utility. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/cc/c-make-pipeline.png" +url="/images/learn-by-example/cc/c-make-pipeline.png" +alt="Compiling a C application in a pipeline" +caption="Compiling a C application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/c-sample-app/blob/master/codefresh.yml) that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/c-sample-app' + revision: master + git: github + compile_my_sources: + title: Compile + stage: build + image: gcc + commands: + - make + run_my_tests: + title: Test + stage: build + image: gcc + commands: + - make test +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, compiles the code and runs unit tests. In all cases we use the public Docker image of Gcc that also contains `make`. + + +## What to read next + +* [C++ example]({{site.baseurl}}/docs/learn-by-example/cc/cpp-cmake/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cc/cpp-cmake.md b/_docs/example-catalog/cc/cpp-cmake.md new file mode 100644 index 00000000..4af30731 --- /dev/null +++ b/_docs/example-catalog/cc/cpp-cmake.md @@ -0,0 +1,126 @@ +--- +title: "Compile and test a C++ application" +description: "Using Codefresh pipelines" +group: learn-by-example +sub_group: cc +toc: true +--- + +Codefresh can work with any C/C++ application very easily as both `gcc` and `g++` are already offered in Dockerhub. There is also another example available with [C and make]({{site.baseurl}}/docs/learn-by-example/cc/c-make). + +## The example C++ project + +You can see the example project at [https://github.com/codefresh-contrib/cpp-sample-app](https://github.com/codefresh-contrib/cpp-sample-app). The repository contains a C++ starter project with a `CMakeLists.txt` file: + +* `cmake .` creates the makefiles. +* `make test` runs unit tests +* `make` compiles the code + +The project is also using the [boost testing libraries](https://www.boost.org/). + +## Cmake, g++ and Docker + +Creating a CI/CD pipeline for C is very easy, because Codefresh can run any [gcc image](https://hub.docker.com/_/gcc/) that you wish. Gcc docker images already contain the `make` utility but not the the `cmake` one. Therefore we will first create a Dockerfile that has `g++`, cmake and the boost libraries. You can follow the same pattern for other development tools that you use. + + +Here is the Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM gcc:9.2 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y cmake libgtest-dev libboost-test-dev && rm -rf /var/lib/apt/lists/* + +CMD ["cmake"] + +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the GCC image +1. Installs cmake and boost +1. Sets cmake as the default command + +## Create a CI pipeline for C++ applications + +We can now use the custom Docker image in order to compile/test the C++ application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/cc/cpp-cmake-pipeline.png" +url="/images/learn-by-example/cc/cpp-cmake-pipeline.png" +alt="Compiling a C++ application in a pipeline" +caption="Compiling a C++ application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/cpp-sample-app/blob/master/codefresh.yml) that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - prepare + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/cpp-sample-app' + revision: master + git: github + build_dev_image: + title: Building Dev Image + stage: prepare + type: build + image_name: cmake + working_directory: ./dev/ + tag: 'latest' + dockerfile: Dockerfile + create_makefiles: + title: Create Makefiles + stage: prepare + image: ${{build_dev_image}} + commands: + - cmake . + compile_my_sources: + title: Compile + stage: build + image: ${{build_dev_image}} + commands: + - make + run_my_tests: + title: Test + stage: build + image: ${{build_dev_image}} + commands: + - make test +{% endraw %} +{% endhighlight %} + +This pipeline: + +1. clones the source code +1. Creates a development docker image that has g++, cmake and boost +1. Runs cmake on the source code to create the make files +1. Compiles the source code +1. Runs unit tests + +You can add additional tools in the pipeline by extending the Dockerfile mentioned in the previous section. You can also +change the version of Gcc/g++ by starting from a different public or private Docker image. + + +## What to read next + +* [C example]({{site.baseurl}}/docs/learn-by-example/cc/c-make/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/cc.md b/_docs/example-catalog/ci-examples/cc.md new file mode 100644 index 00000000..3a94ff95 --- /dev/null +++ b/_docs/example-catalog/ci-examples/cc.md @@ -0,0 +1,10 @@ +--- +title: "C/C++" +description: "How to build C/C++ applications with Codefresh CI/CD pipelines" +group: learn-by-example +toc: true +--- +This section contains Codefresh examples based on C and C++. + +- [C Example with make]({{site.baseurl}}/docs/learn-by-example/cc/c-make) +- [C++ Example with cmake]({{site.baseurl}}/docs/learn-by-example/cc/cpp-cmake) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/general.md b/_docs/example-catalog/ci-examples/general.md new file mode 100644 index 00000000..20d5bd50 --- /dev/null +++ b/_docs/example-catalog/ci-examples/general.md @@ -0,0 +1,16 @@ +--- +title: "General" +description: "" +group: learn-by-example +redirect_from: + - /docs/learn-by-example/general/ +toc: true +--- +This section contains Codefresh examples based on other technologies. +{% comment %} +links not available in base documentation +- [How to trigger the another pipeline using cf-cli](doc:how-to-trigger-another-pipeline-using-cf-cli) +- [How to run composition using cf-cli](doc:how-to-run-composition-using-cf-cli-1) +- [How to spin up image using cf-cli](doc:how-to-spin-up-image-using-cf-cli) +{% endcomment %} +- [Selenium test]({{site.baseurl}}/docs/learn-by-example/general/selenium-test/) diff --git a/_docs/example-catalog/ci-examples/general/selenium-test.md b/_docs/example-catalog/ci-examples/general/selenium-test.md new file mode 100644 index 00000000..be3d80b2 --- /dev/null +++ b/_docs/example-catalog/ci-examples/general/selenium-test.md @@ -0,0 +1,75 @@ +--- +title: "Selenium test" +description: "" +excerpt: "" +group: learn-by-example +sub_group: general +redirect_from: + - /docs/general/selenium-test/ +toc: true +--- +Using this repository, we'll help you get up to speed with basic functionality such as: compiling, testing and building Docker images. + +This project uses `JavaScript, Selenium, Protractor` to build an application which will eventually become a distributable Docker image. + +## Looking around +In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + build_image: + title: Building Image + type: build + dockerfile: Dockerfile + image_name: codefresh/selenium-test + + unit_test: + title: Unit Tests + type: composition + composition: + version: '2' + services: + selenium: + image: selenium/standalone-chrome:2.46.0 + ports: + - 4444:4444 + composition_candidates: + test: + image: ${{build_image}} + volumes: + - /dev/shm:/dev/shm + environment: + GITHUB_ACCOUNT: ${{GITHUB_ACCOUNT}} + GITHUB_PASSWORD: ${{GITHUB_PASSWORD}} + URL: 'https://codefresh.io' + SUITE: 'login' + command: bash -c '/protractor/run-tests.sh' + on_success: + metadata: + set: + - ${{build_image.imageId}}: + - CF_QUALITY: true + on_fail: + metadata: + set: + - ${{build_image.imageId}}: + - CF_QUALITY: false +{% endraw %} +{% endhighlight %} + +{% include image.html +lightbox="true" +file="/images/d0cb57c-codefresh_selenium_env_vars.png" +url="/images/d0cb57c-codefresh_selenium_env_vars.png" +alt="codefresh selenium env vars" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-selenium-test){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} diff --git a/_docs/example-catalog/ci-examples/golang.md b/_docs/example-catalog/ci-examples/golang.md new file mode 100644 index 00000000..71a0f869 --- /dev/null +++ b/_docs/example-catalog/ci-examples/golang.md @@ -0,0 +1,13 @@ +--- +title: "Go" +description: "How to build Golang applications with Codefresh CI/CD pipelines" +group: learn-by-example +redirect_from: + - /docs/go/ + - /docs/golang/ +toc: true +--- +This section contains Codefresh examples based on Go. + +- [Golang Docker Example]({{site.baseurl}}/docs/learn-by-example/golang/golang-hello-world/) +- [Golang with goreleaser]({{site.baseurl}}/docs/learn-by-example/golang/goreleaser/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/java.md b/_docs/example-catalog/ci-examples/java.md new file mode 100644 index 00000000..2229280b --- /dev/null +++ b/_docs/example-catalog/ci-examples/java.md @@ -0,0 +1,15 @@ +--- +title: "Java" +description: "" +group: learn-by-example +redirect_from: + - /docs/java/ +toc: true +--- +This section contains Codefresh examples based on Java: + +- [Spring Boot 2 with Maven]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/) +- [Gradle]({{site.baseurl}}/docs/learn-by-example/java/gradle/) +- [Publish a JAR]({{site.baseurl}}/docs/learn-by-example/java/publish-jar/) +- [Spring MVC JDBC Template]({{site.baseurl}}/docs/learn-by-example/java/spring-mvc-jdbc-template/) + diff --git a/_docs/example-catalog/ci-examples/mobile/android.md b/_docs/example-catalog/ci-examples/mobile/android.md new file mode 100644 index 00000000..6d0b01e9 --- /dev/null +++ b/_docs/example-catalog/ci-examples/mobile/android.md @@ -0,0 +1,81 @@ +--- +title: "Compile and package an Android application" +description: "Using Codefresh pipelines" +group: learn-by-example +sub_group: mobile +toc: true +--- + +Android applications are using Java/Gradle for their build system. Because Codefresh already supports [Gradle]({{site.baseurl}}/docs/learn-by-example/java/gradle/) it is also very easy to build Android projects. + +Any Gradle command can run inside a Docker image that contains the Android SDK. As an example, we will use a [Nextcloud](https://hub.docker.com/r/nextcloudci/android) image from Dockerhub. + + +## The example project + +You can see the example project at [https://github.com/codefresh-contrib/android-sample-app](https://github.com/codefresh-contrib/android-sample-app). The repository contains a Hello World Android project with the following tasks: + +* `./gradlew test` runs unit tests +* `./gradlew build` builds the application + + +## Create a CI pipeline that compiles/releases Android + +In most cases you would create a similar pipeline to a Gradle project. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/mobile/android-ci-pipeline.png" +url="/images/learn-by-example/mobile/android-ci-pipeline.png" +alt="Building and Testing an Android app" +caption="Building and Testing an Android app" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/android-sample-app/blob/master/codefresh.yml) that uses a Docker image with the Android SDK in order to run Gradle. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/android-sample-app' + revision: master + git: github + TestIt: + title: Running Tests + stage: test + image: nextcloudci/android:android-48 + commands: + - chmod +x ./gradlew + - ./gradlew test --no-daemon --gradle-user-home=/codefresh/volume/.gradle + BuildIt: + title: Packaging Android App + stage: build + image: nextcloudci/android:android-48 + commands: + - ./gradlew build --no-daemon --gradle-user-home=/codefresh/volume/.gradle +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, runs unit tests and finally builds the Android application. + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#how-caching-works-in-codefresh) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Gradle cache we make sure that Codefresh will cache automatically the Gradle libraries resulting in much faster builds. + + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/ci-examples/nodejs.md b/_docs/example-catalog/ci-examples/nodejs.md new file mode 100644 index 00000000..0f5cc4fe --- /dev/null +++ b/_docs/example-catalog/ci-examples/nodejs.md @@ -0,0 +1,14 @@ +--- +title: "Node.js" +description: "" +group: learn-by-example +redirect_from: + - /docs/nodejs/ +toc: true +--- + +This section contains Codefresh examples based on Node.js: + +- [Let's Chat]({{site.baseurl}}/docs/learn-by-example/nodejs/lets-chat/) - Express.js + Mongo Example +- [Voting app]({{site.baseurl}}/docs/learn-by-example/nodejs/voting-app/) - Microservices app with multiple programming languages +- [React JS app]({{site.baseurl}}/docs/learn-by-example/nodejs/react/) - React.JS + multi stage Docker build example \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/python.md b/_docs/example-catalog/ci-examples/python.md new file mode 100644 index 00000000..76f5c347 --- /dev/null +++ b/_docs/example-catalog/ci-examples/python.md @@ -0,0 +1,11 @@ +--- +title: "Python" +description: "" +group: learn-by-example +redirect_from: + - /docs/python/ +toc: true +--- +This section contains Codefresh examples based on Python. +- [Voting app]({{ site.baseurl }}/docs/learn-by-example/python/voting-app/) +- [Django]({{ site.baseurl }}/docs/learn-by-example/python/django/) diff --git a/_docs/example-catalog/ci-examples/scala.md b/_docs/example-catalog/ci-examples/scala.md new file mode 100644 index 00000000..5a0991f4 --- /dev/null +++ b/_docs/example-catalog/ci-examples/scala.md @@ -0,0 +1,10 @@ +--- +title: "Scala" +description: "" +group: learn-by-example +redirect_from: + - /docs/scala/ +toc: true +--- +This section contains Codefresh examples based on Scala. +- [Scala: Hello World]({{site.baseurl}}/docs/learn-by-example/scala/scala-hello-world/) diff --git a/_docs/example-catalog/codacy-testing.md b/_docs/example-catalog/codacy-testing.md new file mode 100644 index 00000000..bda8c5e5 --- /dev/null +++ b/_docs/example-catalog/codacy-testing.md @@ -0,0 +1,173 @@ +--- +title: "Codacy Coverage Reports" +description: "How to forward coverage reports to Codacy" +group: yaml-examples +toc: true +--- + +[Codacy](https://www.codacy.com/) is a code review tool that allows for automatic analysis, code coverage tracking, and extensive reports to allow you and your team to improve your code quality over time. + +Analysis reports displayed within Codacy dashboard: +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-report.png" +url="/images/testing/codacy/codacy-report.png" +alt="Codacy UI with coverage reports" +max-width="100%" +%} + +## Prerequisites for using Codacy + +* A simple [Codefresh pipeline up and running](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +* A [Codacy account](https://www.codacy.com/) (free, pro or enterprise) +* A testing tool added to your project that produces coverage reports + +Codacy supports over [30 different language integrations](https://docs.codacy.com/getting-started/supported-languages-and-tools/). Depending on the programming language used, it requires little to no set-up. + +You could try it out by cloning our [node example application](https://github.com/codefresh-contrib/codacy-sample-app) that utilises [jest](https://jestjs.io/). + +## Create an Account with Codacy +[Codacy has a free version](https://www.codacy.com/), a pro version, and an on-premises version. The latter two have a free trial, which allows you to test all features over the course of two weeks. You can sign-up via GitHub, Bitbucket, or GitLab. + +When you log into Codacy for the first time, it will ask you to provide access to a repository. At this stage, Codacy will not download any code from your repository but merely access its names. You can then either provide access to selective repositories or your entire git account. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-add-repo.png" +url="/images/testing/codacy/codacy-add-repo.png" +alt="Add repository to codacy" +max-width="80%" +%} + +## Generate Project API token +To use Codacy, we need a project API token. To generate the token, select your project => go to settings => integrations => add integration => select “Project API”. Make sure that you select the API token from here and not your general project settings. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/create-api-token.png" +url="/images/testing/codacy/create-api-token.png" +alt="Create Project API token" +max-width="80%" +%} + +## Codefresh Pipeline + +In case the project that you want to use Codacy in does not have a pipeline, [create a new pipeline](https://codefresh.io/docs/docs/getting-started/create-a-basic-pipeline/). + +{% include image.html +lightbox="true" +file="/images/testing/codacy/create-codacy-pipeline.png" +url="/images/testing/codacy/create-codacy-pipeline.png" +alt="Create Codacy Pipeline" +max-width="80%" +%} + +**Setting-up step** + +This step is based on our [TypeScript application](https://github.com/codefresh-contrib/codacy-sample-app). Before we are going to set-up our pipeline, we are going to add our Project API token as our environment variable. Note that we have specified our token in the variables section on the right, like displayed in the following screenshot. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-variable.png" +url="/images/testing/codacy/codacy-variable.png" +alt="Provide Codacy ENV variable" +max-width="80%" +%} + +Once the variable is called through the [Codefresh yml syntax](https://codefresh.io/docs/docs/codefresh-yaml/variables/), it will automatically use the value provided within the variables section. If you are using this example as your pipeline, please delete anything in your pipeline. We can then add the following pipeline to our Inline YAML within the Workflow section in our UI: + +{% highlight yaml %} +{% raw %} +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "build" + - "test" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "anais-codefresh/codacy-sample-app" + # CF_BRANCH value is auto set when pipeline is triggered + # Learn more at codefresh.io/docs/docs/codefresh-yaml/variables/ + revision: "${{CF_BRANCH}}" + git: "github" + stage: "clone" + + build: + title: "Building Docker image" + type: "build" + image_name: "anaisurlichs/codacy-sample-app" + working_directory: "${{clone}}" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + registry: "dockerhub" + + tests: + title: "Running test" + type: "freestyle" + working_directory: '${{clone}}' + arguments: + image: 'node:15.2' + commands: + - "npm install --save-dev jest" + - "npm run test" + stage: "test" + + codacy: + title: "Pushing reports to codacy" + type: "freestyle" + working_directory: '${{clone}}' + arguments: + image: 'alpine:3.8' + commands: + - "export CODACY_PROJECT_TOKEN=${{CODACY_PROJECT_TOKEN}}" + - "wget -qO - https://coverage.codacy.com/get.sh | sh" + stage: "test" +{% endraw %} +{% endhighlight %} + +The last two steps, ’tests’ and ’codacy’, are used to run our tests, create our coverage reports and forward those to Codacy. If you are using your own project and existing pipeline, add those two steps to your pipeline. In case you are using your own application, make sure to adapt the commands within the test step to run the tests of your application. Additionally, ensure that both the ’repo’ and the ’image_name’ point to your integrations. + +Once you run the pipeline the steps will create the coverage report and forward it to Codacy. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-pipeline.png" +url="/images/testing/codacy/codacy-pipeline.png" +alt="Pipeline with Codacy step" +max-width="80%" +%} + +## View reports + +This will allow you to view the updated coverage reports within Codacy's UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-report.png" +url="/images/testing/codacy/codacy-report.png" +alt="Codacy UI Analysis Dashboard" +max-width="80%" +%} + +You can access further information on the coverage report by opening the file tab and accessing a specific file from your repository. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/file-analysis.png" +url="/images/testing/codacy/file-analysis.png" +alt="Codacy report details" +max-width="90%" +%} + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +* [Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) \ No newline at end of file diff --git a/_docs/example-catalog/codecov-testing.md b/_docs/example-catalog/codecov-testing.md new file mode 100644 index 00000000..a0855bd9 --- /dev/null +++ b/_docs/example-catalog/codecov-testing.md @@ -0,0 +1,126 @@ +--- +title: "Codecov Coverage Reports" +description: "How to forward coverage reports to Codecov" +group: yaml-examples +toc: true +--- + +[Codecov account](https://codecov.io/) is a code analysis tool with which users can group, merge, archive, and compare coverage reports. Code coverage describes which lines of code were executed by the test suite and which ones were not. However, this is not to be confused with a testing tool. + +Analysis reports displayed within the Codecov dashboard: +{% include image.html +lightbox="true" +file="/images/testing/codecov/analysis-report.png" +url="/images/testing/codecov/analysis-report.png" +alt="Codecov UI Analysis reports" +max-width="50%" +%} + +## Prerequisites for using Codecov + +* A simple [Codefresh pipeline up and running](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +* A [Codecov account](https://codecov.io/) (free or enterprise) +* A testing tool added to your project that produces coverage reports + +Note that reports should ideally be written in .json, .xml, or txt. To be sure, please double check that your coverage [report format](https://docs.codecov.io/docs/supported-report-formats) is supported. You can find a variety of examples for different programming languages and suggestions for respective testing tools in the [Codecov docs](https://docs.codecov.io/docs/supported-languages). + +To test Codecov and follow along with the next section, you can clone our [Codecov sample app](https://github.com/codefresh-contrib/codecov-sample-app). + +## Create a Codecov Account + +Once you sign-up to Codecov, you can add a new repository. The UI will then provide you with an access token to the repository. While it is recommended that you take note of the token, you will still be able to access it within the **Settings** tap. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-interface.png" +url="/images/testing/codecov/codecov-interface.png" +alt="Codecov Project Repository UI" +max-width="50%" +%} + +## Codefresh Pipeline + +In this case, we have divided the testing and connecting Codefresh to Codecov into two different steps. If they can be run within the same image, you could also connect them. + +**Testing step** +Will run the command(s) for our testing tool. This will generate the code coverage report upon running the pipeline. Please refer to the Codecov documentation for [supported testing frameworks](https://docs.codecov.io/docs/supported-report-formats). The [README of each example](https://docs.codecov.io/docs/supported-languages) refers to possible frameworks that can be used. + +In general, ensure that the framework you use for testing and generating code coverage reports: +* Produce code coverage reports in the supported file format +* Is compatible with the programming language that your program is written in + +{% highlight yaml %} +{% raw %} + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:14.19.0" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "npm install --save-dev jest" + - "npx jest --coverage" + stage: "test" +{% endraw %} +{% endhighlight %} + +**Codecov step** + +{% highlight yaml %} +{% raw %} +upload: + title: "Running test" + type: "freestyle" # Run any command + image: "node:14.19.0" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "ci_env=`curl -s https://codecov.io/env`" + - "npm install codecov -g" + - "codecov -t ${{CODECOV_TOKEN}} -f ./coverage/clover.xml" + stage: "upload" +{% endraw %} +{% endhighlight %} + +The commands run inside of the node Docker image: +* `ci_env= curl -s https://codecov.io/env` -- Here we set the CI environment variable to take note that we are using Codefresh +* `npm install codecov -g` -- This installs the odecov CLI +* `codecov -t ${{CODECOV_TOKEN}} -f ./coverage/clover.xml` -- Here we set the Codevoc access token provided in the UI when we connect to a new git repository and point to the file that contains our coverage report. + +Once you run the pipeline the steps will create the coverage report and forward it to Codecov. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-pipeline.png" +url="/images/testing/codecov/codecov-pipeline.png" +alt="Pipeline with codecov step" +max-width="50%" +%} + +## View reports + +This will allow you to view the updated coverage reports within the Codecov UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-report.png" +url="/images/testing/codecov/codecov-report.png" +alt="Pipeline with codecov step" +max-width="50%" +%} + +You can access further information on the coverage report by opening the link to the file displayed in the table. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-report-details.png" +url="/images/testing/codecov/codecov-report-details.png" +alt="Codecov report details" +max-width="50%" +%} + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +* [Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) diff --git a/_docs/example-catalog/coveralls-testing.md b/_docs/example-catalog/coveralls-testing.md new file mode 100644 index 00000000..bd0b3f30 --- /dev/null +++ b/_docs/example-catalog/coveralls-testing.md @@ -0,0 +1,218 @@ +--- +title: "Coveralls Coverage Reports" +description: "How to forward coverage reports to Coveralls" +group: yaml-examples +toc: true +--- + +[Coveralls](https://coveralls.io/) is a web service that allows users to track the code coverage of their application over time in order to optimize the effectiveness of their unit tests. This section details how coverage reports can be generated and forwarded to Coveralls with every Codefresh build. + +Analysis reports displayed within Coveralls dashboard: +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-sample-app.png" +url="/images/testing/coveralls/coveralls-sample-app.png" +alt="Coveralls UI Analysis reports" +max-width="80%" +%} + +## Prerequisites for using Coveralls + +* A simple [Codefresh pipeline up and running](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +* A [Coveralls account](https://coveralls.io/) (free or enterprise) -- Note that all open-source projects are free on Coveralls +* A testing tool added to your project that produces coverage reports + +Coveralls supports [22 different language integrations](https://docs.coveralls.io/about-coveralls). Each example provided in the official documentation suggests several coverage report tools that can be used in combination with Coveralls. + +You could try it out by cloning our [node example application](https://github.com/codefresh-contrib/coveralls-sample-app) that utilises [jest](https://jestjs.io/). + +## Prepare your Repository + +If you are using your own application as an example, you have to make a few modifications to the repository. Please have a look at the Coveralls example section for other languages. + +First, install Coveralls in your project: +{% highlight yaml %} +{% raw %} +npm install coveralls --save-dev +{% endraw %} +{% endhighlight %} + +Coveralls requires a [script](https://github.com/nickmerwin/node-coveralls) that takes standard input and sends it to coveralls.io to report your code coverage. Depending on the framework that you are using, you will have to add a different script to your application. + +Any coverage reports can be forwarded that are within a [lcov data format](http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php) (including [mocha's LCOV reporter](https://www.npmjs.com/package/mocha-lcov-reporter)). For this, we are going to set-up a “bin” folder, and within the folder a coveralls.js file that contains the following content: + +{% highlight yaml %} +{% raw %} +#!/usr/bin/env node + +'use strict'; + +const { handleInput } = require('..'); + +process.stdin.resume(); +process.stdin.setEncoding('utf8'); + +let input = ''; + +process.stdin.on('data', chunk => { + input += chunk; +}); + +process.stdin.on('end', () => { + handleInput(input, err => { + if (err) { + throw err; + } + }); +}); +{% endraw %} +{% endhighlight %} + +## Create an Account with Coveralls + +Once you sign-up to Coveralls, you can add a new repository. The UI will then provide you with an access token to the repository. Take note of the token since it will be required in the next sections. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/add-repository.png" +url="/images/testing/coveralls/add-repository.png" +alt="Coveralls repository" +max-width="80%" +%} + +## Codefresh Pipeline + +In case the project that you want to use Coveralls in does not have a pipeline, [create a new pipeline](https://codefresh.io/docs/docs/getting-started/create-a-basic-pipeline/). + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/create-coveralls-pipeline.png" +url="/images/testing/coveralls/create-coveralls-pipeline.png" +alt="Create Coveralls Pipeline" +max-width="80%" +%} + +Once you ’create’ the pipeline, a standard codefresh.yml file is generated with three steps: +* The first step will clone your repository; +* The second step will both, build and push your repository to the container registry that you have connected with Codefresh; +* And the third step currently does not do much. +In the next section, we will modify the testing step. + +**Testing step** + +The testing step requires three different environment variables to connect to Coveralls: +* `export COVERALLS_SERVICE_NAME="codefresh"` +* `export COVERALLS_GIT_BRANCH="insert the branch that you will be using with your application"` +* `export COVERALLS_REPO_TOKEN="insert the secret repo token from coveralls.io"` + +{% highlight yaml %} +{% raw %} + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:15.2" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "export COVERALLS_SERVICE_NAME=${{COVERALLS_SERVICE_NAME}}" + - "export COVERALLS_GIT_BRANCH=${{CF_BRANCH}}" + - "export COVERALLS_REPO_TOKEN=${{COVERALLS_REPO_TOKEN}}" + - "npm install --save-dev jest" + - "npm run test" + stage: "test" +{% endraw %} +{% endhighlight %} + +We specify several variables within this step. Those, which start with ’CF’ are [Codefresh-specific steps](https://codefresh.io/docs/docs/codefresh-yaml/variables/) and the value is automatically provided by Codefresh once you run the pipeline. Our entire codefresh.yml will look as such: + +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "test" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "anais-codefresh/coveralls-sample-app" + # CF_BRANCH value is auto set when pipeline is triggered + # Learn more at codefresh.io/docs/docs/codefresh-yaml/variables/ + revision: "${{CF_BRANCH}}" + git: "github" + stage: "clone" + + build: + title: "Building Docker image" + type: "build" + image_name: "anaisurlichs/coveralls-sample-app" + working_directory: "${{clone}}" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + registry: "dockerhub" + + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:15.2" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "export COVERALLS_SERVICE_NAME=${{COVERALLS_SERVICE_NAME}}" + - "export COVERALLS_GIT_BRANCH=${{CF_BRANCH}}" + - "export COVERALLS_REPO_TOKEN=${{COVERALLS_REPO_TOKEN}}" + - "npm install --save-dev jest" + - "npm run test" + stage: "test" +{% endraw %} +{% endhighlight %} + +Once you run the pipeline the steps will create the coverage report and forward it to Coveralls. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-pipeline.png" +url="/images/testing/coveralls/coveralls-pipeline.png" +alt="Pipeline with Coveralls step" +max-width="80%" +%} + +## View reports + +This will allow you to view the updated coverage reports within Coveralls UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-sample-app.png" +url="/images/testing/coveralls/coveralls-sample-app.png" +alt="Coveralls UI Analysis reports" +max-width="80%" +%} + +You can access further information on the coverage report by opening the link to the file displayed in the table. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-specific-report.png" +url="/images/testing/coveralls/coveralls-specific-report.png" +alt="Coveralls report details" +max-width="80%" +%} + +And view a the code coverage of a specific file: +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-coverage.png" +url="/images/testing/coveralls/coveralls-coverage.png" +alt="Coveralls report details" +max-width="80%" +%} + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +* [Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) \ No newline at end of file diff --git a/_docs/example-catalog/decryption-with-mozilla-sops.md b/_docs/example-catalog/decryption-with-mozilla-sops.md new file mode 100644 index 00000000..495e1785 --- /dev/null +++ b/_docs/example-catalog/decryption-with-mozilla-sops.md @@ -0,0 +1,179 @@ +--- +title: "Decryption with Mozilla SOPS" +description: "Store secrets in your repository and decrypt them using Mozilla SOPS" +group: yaml-examples +sub_group: examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A public and private GnuGP key pair +- A credentials yaml, that is encrypted using Mozilla SOPS, and stored in your repository + +## The Example Java Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/mozilla-sops-app). + +The example application retrieves the system variable "password," from the pipeline and uses it to authenticate to a Redis database, but you are free to use any type of database of your choosing. + +```java + String password = System.getenv("password"); + String host = System.getProperty("server.host"); + + RedisClient redisClient = new RedisClient( + RedisURI.create("redis://" + password + "@" + host + ":6379")); + RedisConnection connection = redisClient.connect(); +``` + +Also in the example application is a simple unit test that ensures we are able to read and write data to the database. + +An encrypted credentials file is stored in the repository (along with a public key): + +`credentials.yaml` +```yaml +password: ENC[AES256_GCM,data:Jsth2tY8GhLgj6Jct27l,iv:3vcKVoD5ms29R5SWHiFhDhSAvvJTRzjn9lA6woroUQ8=,tag:OjkLvcHxE4m5RSCV7ej+FA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + lastmodified: '2020-03-30T19:12:49Z' + mac: ENC[AES256_GCM,data:jGMTkFhXjgGMdWBpaSWjGZP6fta3UuYjEsnqziNELQZ2cLScT9v+GKg/c8iJYv1Gfiz3aw4ivYYrWzwmZehIbPHaw3/XBv/VRCQhzRWYKaf6pPFUXIS7XALSf9L9VbGOXL/CGPRae3t3HpaOor+knd6iQk2WR3K9kSeib4RBSCE=,iv:WSP8hBwaBv3ymTGltBOaVVC1sT08IG4hwqESlG8rN9w=,tag:3hZvCuql+ASWe/Mm5Bl7xg==,type:str] + pgp: + - created_at: '2020-03-30T19:12:49Z' + enc: | + -----BEGIN PGP MESSAGE----- + hQGMA9TqgBq6RQVRAQv/UouNaHfxkJ5PwXLvda97Fgj/2ew2VXPAlAnLvoGvTsb2 + U4GXcaE7c4mYf7wSKF9k/F0FZTUEnd3CRji/OqjrNyvj5zI/9KGRABCKvzjsx+ZG + JolVnDifHl78Mor1CUPQ4JXasHKbVSlNLMGgDHIsvpeC7f7pIi8YDUDIa3/zXhFK + jcKzz4nlrW1Ph8zukmQk49Xvv6+DFj2NTptOB3U6mh79RCdnyCSRHxA3f0X00Pi5 + g0p5x46S5E04uC2wXrZv8i/gyQbLHxwjmdbLq+P1Peu4/i9eSZZOpx0mc1KJ2mjr + oKRvgnUFz3xuYrSNzjC1vM01UbuSytlwx+S3J7VVLPSZRso1sbgv2+ylUOAHS+gZ + 64uL0j/BZrF4wZI8y8zr0nJ6cZLiiF3LeXhfcuWJJ7+5p1OBEvfO+sWorLahIZTw + pogYPDpz4rGnrJRKBkNsVlYuUG8aNerIfhEBr6n//VJtt7QXTEXraLCTt4a6z/Fl + R6YSeNCKWQlURrTfm4Kv0lwBzMTLUb+Fg3HO8ShhiE9/2dKTSJkRJMVXRDp22Fm1 + vO/wMFUjg6Dkrj1LVqQ9zcXc5QElgc4mF/V7SazacbQ7/g67tVtUrTit9LXgR9A0 + k7wU5iT5oWLJtWwpkA== + =Il2p + -----END PGP MESSAGE----- + fp: C70833A85193F72C2D72CB9DBC109AFC69E0185D + encrypted_regex: password + version: 3.5.0 +``` +You cannot run the application locally, as it needs to run in the pipeline in order to use our environment variables to connect. + +## Create the Pipeline + +Our pipeline will contain four stages: + +- A stage for cloning +- A stage for importing the private/public keypair +- A stage for decrypting the credentials file +- A stage for packaging our jar and running unit tests + +{% include image.html +lightbox="true" +file="/images/examples/secrets/mozilla-sops-pipeline.png" +url="/images/examples/secrets/mozilla-sops-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +First, you will need to add a pipeline variable, `PRIV_KEY`, for your private key. You can do that in the UI by navigating to the in-line YAML editor and to the right-hand side, you will find the **Variables** tab: + +{% include image.html +lightbox="true" +file="/images/examples/secrets/mozilla-sops-pipeline-vars.png" +url="/images/examples/secrets/mozilla-sops-pipeline-vars.png" +alt="Mozilla SOPS Pipeline Variables" +caption="Pipeline Variables" +max-width="90%" +%} + +You can also add this [directly in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables). + +Here is the entire pipeline: + +`codefresh.yaml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/yaml-examples/examples/ + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "import" + - "decrypt" + - "package" + +steps: + clone: + title: "Cloning repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/mozilla-sops-app" + revision: "master" + + import_keys: + title: "Importing gpg keys..." + type: "freestyle" + stage: "import" + working_directory: '${{clone}}' + arguments: + image: "vladgh/gpg" + commands: + - gpg --import public.key + - echo -e "${{PRIV_KEY}}" > private.key + - gpg --allow-secret-key-import --import private.key + + decrypt_password: + title: "Decrypting password..." + type: "freestyle" + working_directory: "${{clone}}" + stage: "decrypt" + arguments: + image: "mozilla/sops" + commands: + - cp -r /codefresh/volume/.gnupg /root/.gnupg + - cf_export password=$(sops --decrypt --extract '["password"]' credentials.yaml) + + package_jar: + title: "Packaging jar and running unit tests..." + working_directory: ${{clone}} + stage: "package" + arguments: + image: "maven:3.5.2-jdk-8-alpine" + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dserver.host=my-redis-db-host clean package + services: + composition: + my-redis-db-host: + image: 'redis:4-alpine' + command: 'redis-server --requirepass $password' + ports: + - 6379 +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that uses a GPG image and imports the public and private key pair +3. A freestyle step that decrypts the credentials file. At this step, SOPS is looking for the .gnupg directory (where the keyring is stored) under /root. We need to copy it from the [Codefresh Volume]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/#custom-volumes), as /root is not saved between containers. +4. The last step, `package_jar`, does a few special things to take note of: + - Spins up a [Service Container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) running Redis on port 6379 , and sets the password to the database using our exported environment variable + - Sets `maven.repo.local` to cache Maven dependencies into the local codefresh volume to [speed up builds]({{site.baseurl}}/docs/example-catalog/java/spring-boot-2/#caching-the-maven-dependencies) + - Runs unit tests and packages the jar. Note how you can directly refer to the service container's name (`my-redis-db-host`) when we set `server.host` + +## What to Read Next + +- [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Vault Secrets in the Pipeline]({{site.baseurl}}/docs/yaml-examples/examples/vault-secrets-in-the-pipeline/) + diff --git a/_docs/example-catalog/deploy-to-heroku.md b/_docs/example-catalog/deploy-to-heroku.md new file mode 100644 index 00000000..d724a90f --- /dev/null +++ b/_docs/example-catalog/deploy-to-heroku.md @@ -0,0 +1,213 @@ +--- +title: "Deploy to Heroku" +description: "Deploying your application or image to Heroku" +group: yaml-examples +sub_group: examples +toc: true +--- + +Heroku is a container-based cloud PaaS software that allows you to deploy, run, and manage your applications. Built on top of AWS, it supports Ruby, Node.js, Java, Python, Clojure, Scala, Go and PHP. + +This tutorial will cover two examples, depending on your use case. If you are not using containers, your use case is covered using the Codefresh heroku-deployer plugin ([Example #1](#pipeline-example-1-deploying-source-code-to-heroku-using-the-codefresh-heroku-plugin)). If you are using containers, you can achieve deployment by using a combination of build, push, and freestyle steps ([Example #2](#pipeline-example-2-deploy-a-docker-image-to-heroku)). + +## The Example Django Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/heroku-python-django-sample-app). + +The repository contains a Django starter project with the following commands: + +- `pip install -r requirements.txt` to install dependencies. +- `python -m unittest composeexample.utils` runs unit tests. +- `python manage.py runserver 0.0.0.0:8000` to start the application locally. + +Once launched the application presents the Django starter page at localhost:8000. + +## Pipeline Example #1: Deploying Source Code to Heroku Using the Codefresh Heroku Plugin + +### Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A [free Heroku account](https://signup.heroku.com) +- A Heroku API token (you can find this under **Account Settings** and then scrolling down, you will find the API Key) + +### Create the Pipeline + +This pipeline will have three stages: clone, test, and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-pipeline.png" +url="/images/examples/deployments/heroku-deployer-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the environment variables in the deploy stage to your respective values. You can do this directly [in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables), or through the Codefresh UI. Navigate to the in-line editor, and to the right you will find a tab lebeled **Variables**. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-variables2.png" +url="/images/examples/deployments/heroku-deployer-variables2.png" +alt="Codefresh UI Pipeline Variables View" +caption="Codefresh UI Pipeline Variables View" +max-width="100%" +%} + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - clone + - test + - deploy +steps: + clone: + title: "Cloning main repository..." + stage: "clone" + type: "git-clone" + arguments: + repo: "codefresh-contrib/heroku-python-django-sample-app" + revision: "master" + git: "github" + run_unit_tests: + title: "Running unit tests..." + stage: "test" + type: "freestyle" + working_directory: "${{clone}}" + arguments: + image: "python:3.6-slim" + commands: + - "pip install -r requirements.txt --cache-dir=/codefresh/volume/pip-cache" + - "python -m unittest composeexample.utils" + deploy_to_heroku: + title: "Deploying to Heroku..." + stage: "deploy" + type: "heroku-deployer" + arguments: + APP_NAME: $APP_NAME + EMAIL: $EMAIL + API_TOKEN: $API_TOKEN +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that installs dependencies and runs the unit tests +3. A freestyle step that deploys the application to Heroku using the heroku-deployer plugin from the [Step Marketplace](https://codefresh.io/steps/step/heroku-deployer) + +## Pipeline Example #2: Deploy a Docker Image to Heroku + +This example differs from the plugin usage, as it will deploy a built Docker image to Heroku. + +Note that you need to change the environment variables to your respective values. You can do this directly [in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables), or through the Codefresh UI. Navigate to the in-line editor, and to the right you will find a tab lebeled **Variables**. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-variables.png" +url="/images/examples/deployments/heroku-deployer-variables.png" +alt="Codefresh UI Pipeline Variables View" +caption="Codefresh UI Pipeline Variables View" +max-width="100%" +%} + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A [free Heroku account](https://signup.heroku.com) +- An empty repository already created in Heroku using the `heroku create ` command +- A Heroku registry [connected to Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/other-registries/#heroku-registries) +- A Heroku API token (you can find this under **Account Settings** and then scrolling down, you will find the API Key) + +### Create the Pipeline + +This pipeline will have five stages: clone, build, test, push, and release. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-vanilla-push-pipeline.png" +url="/images/examples/deployments/heroku-vanilla-push-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +`codefresh-heroku-push-image.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +version: '1.0' +stages: + - clone + - build + - test + - push + - release +steps: + clone: + title: "Cloning main repository..." + stage: "clone" + type: "git-clone" + arguments: + repo: "codefresh-contrib/heroku-python-django-sample-app" + revision: "master" + git: "github" + build: + title: "Building Docker Image..." + stage: "build" + type: "build" + working_directory: "./heroku-python-django-sample-app" + arguments: + image_name: "${{IMAGE_NAME}}" + tag: "master" + dockerfile: "Dockerfile" + run_unit_tests: + title: "Running unit tests..." + stage: "test" + type: "freestyle" + working_directory: "./heroku-python-django-sample-app" + arguments: + image: '${{build}}' + commands: + - "python -m unittest composeexample.utils" + push_image: + title: "Pushing image to Heroku..." + stage: "push" + type: "push" + arguments: + candidate: '${{build}}' + image_name: "${{IMAGE_NAME}}/web" + registry: "heroku" + release_image: + title: "Releasing image..." + stage: "release" + type: "freestyle" + arguments: + image: "nazarcodefresh/heroku-cli:alpine" + commands: + - >- + printf "machine api.heroku.com\n login $EMAIL\n password + $API_TOKEN\nmachine git.heroku.com\n login $EMAIL\n password + $API_TOKEN\n" > ~/.netrc + - "heroku container:release --app $IMAGE_NAME web" +{% endraw %} +{% endhighlight %} + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that builds our Docker image +3. A freestyle step that runs unit tests on our Docker image +3. A [push]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) step that pushes to the Heroku registry +4. A freestyle step that releases the Docker image + + +## What to Read Next + +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Push Step]({{site.baseurl}}/docs/codefresh-yaml/steps/push/) diff --git a/_docs/example-catalog/deploy-to-tomcat-via-scp.md b/_docs/example-catalog/deploy-to-tomcat-via-scp.md new file mode 100644 index 00000000..320d0e5b --- /dev/null +++ b/_docs/example-catalog/deploy-to-tomcat-via-scp.md @@ -0,0 +1,123 @@ +--- +title: "Deploy to a VM via SCP" +description: "Deploying your application to Tomcat using SCP" +group: yaml-examples +sub_group: examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A distribution of [Tomcat](https://tomcat.apache.org/download-90.cgi) setup on a remote server (running with port 8080 exposed) + +## The Example Java Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/scp-war-app). + +The example application is a simple Hello World Java application using the [Spark Java framework](http://sparkjava.com/): + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-hello-world.png" +url="/images/examples/deployments/scp-hello-world.png" +alt="Hello World!" +caption="Hello World!" +max-width="100%" +%} + + +```java + @Override + public void init() { + get("/hello", (req, res) -> "Hello World"); + } +``` + +## Create the Pipeline + +Our pipeline will have three stages: clone, package, and transfer. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-pipeline.png" +url="/images/examples/deployments/scp-pipeline.png" +alt="SCP pipeline" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the environment variables under the `transfer` step to your respective values. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/yaml-examples/examples/ + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "package" + - "transfer" + +steps: + clone: + title: "Cloning repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/scp-war-app" + + package: + title: "Packaging war..." + type: "freestyle" + stage: "package" + arguments: + image: "maven:3.5.2-jdk-8-alpine" + working_directory: "${{clone}}" + commands: + - "mvn -Dmaven.repo.local=/codefresh/volume/m2_repository clean package" + + transfer: + title: "Transferring war to Tomcat..." + type: "freestyle" + stage: "transfer" + arguments: + image: "ictu/sshpass:latest" + working_directory: "${{package}}/target" + environment: + - USER= + - HOST= + - PASSWORD= + - TOMCAT_DIR= + commands: + - "echo | ssh-keygen -P '' -t rsa" + - "sshpass -p $PASSWORD ssh-copy-id -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $USER@$HOST" + - "scp sparkjava-hello-world-1.0.war $USER@$HOST:$TOMCAT_DIR" +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that installs the dependencies via Maven and packages our war file +3. A freestyle step that transfers our application via scp to a Tomcat server. Note that you will need to change the listed environment variables accordingly, either through the YAML itself, or through your pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-variables.png" +url="/images/examples/deployments/scp-variables.png" +alt="Pipeline variables" +caption="Pipeline variables" +max-width="100%" +%} + +## What to Read Next + +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Deploying to a VM using FTP]({{site.baseurl}}/docs/yaml-examples/examples/transferring-php-ftp/) diff --git a/_docs/example-catalog/deploy-with-kustomize.md b/_docs/example-catalog/deploy-with-kustomize.md new file mode 100644 index 00000000..8b5dac97 --- /dev/null +++ b/_docs/example-catalog/deploy-with-kustomize.md @@ -0,0 +1,248 @@ +--- +title: "Deploy to Kubernetes with Kustomize" +description: "Deploy your services to Kubernetes using Kustomize" +group: yaml-examples +sub_group: examples +toc: true +--- + +[Kustomize](https://kustomize.io) is a tool included with kubectl 1.14 that "lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is." + +Kustomize is more of an overlay engine, as opposed to a templating engine. You create a base configuration and overlays. Your overlays contain a *kustomization.yaml* file, and any variants/changes are applied over top of the base configuration. Kustomize does not use templates at all. + +While it is good for simple scenarios, we suggest that you use Helm for managing your Kubernetes applications. Helm is a full package manager for Kubernetes manifests that also provides templating capabilities. See [this example]({{site.baseurl}}/docs/yaml-examples/examples/helm/) for more information. + +## The Example Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/kustomize-sample-app). + +The sample application is a simple Spring Boot web app, that displays an environment variable, `MY_MYSQL_DB` on the page: + +```java +public class HelloController { + + String my_sql_db = System.getenv("MY_MYSQL_DB"); + + @RequestMapping("/") + public String index() { + return my_sql_db; + } +``` + +The project contains a [base](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#base) and two [overlays](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#overlay), one for a staging environment and one for production. + +The base manifest holds a dummy variable for `MY_MYSQL_DB` which will be overlayed once we call the kustomize command in our pipeline. + +`base/deployment.yaml` +```yaml +... + env: + - name: MY_MYSQL_DB + valueFrom: + configMapKeyRef: + name: the-map + key: mysqlDB +``` + +We will overlay on top of the manifests a different value for `MY_MYSQL_DB` for the staging environment and production environment. + +`overlays/staging/config-map.yaml` +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: the-map +data: + mysqlDB: "staging-mysql.example.com:3306" +``` + +`overlays/production/config-map.yaml` +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: the-map +data: + mysqlDB: "prod-mysql.example.com:3306" +``` + +In addition, for the production environment, the number of replicas will be overlayed to 3 instead of 1 (as [defined in the base deployment](https://github.com/codefresh-contrib/kustomize-sample-app/blob/32e683f82940de0bf2de2da40fa6b150e2b24b23/base/deployment.yaml#L8)). + +`overlays/production/deployment.yaml` +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: the-deployment +spec: + replicas: 3 +``` + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A Kubernetes cluster [connected to your Codefresh account](https://codefresh.io/docs/docs/deploy-to-kubernetes/add-kubernetes-cluster/) + +## Create the Staging Environment Pipeline + +This pipeline will have two stages: clone and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-staging-pipeline.png" +url="/images/examples/deployments/k8s-kustomize-staging-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line pipeline editor of the Codefresh UI. However, make sure to replace cluster context for the kubectl command under the arguments section with your own that you integrated with Codefresh. It will automatically clone the project for you and deploy. + +`staging-codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/yaml-examples/examples/ + +version: "1.0" +# Stages can help you organize your steps in stages + +stages: + - clone + - deploy + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: clone + arguments: + repo: https://github.com/codefresh-contrib/kustomize-sample-app.git + git: github + revision: master + + deploy: + title: Deploying to Staging using Kustomize... + type: freestyle + stage: deploy + working_directory: ${{clone}} + arguments: + image: codefresh/kubectl:1.14.9 + commands: + - kubectl config use-context anna-sandbox@codefresh-support + - kubectl apply -k overlays/staging +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that: + - Uses kubectl to connect to our Kubernetes cluster we have integrated with Codefresh + - Using Kustomize (the -k flag), deploys the application as a staging environment with the appropriate value for `MY_MYSQL_DB` as defined in our configMap + +>Note that if you are using kubectl prior to 1.14, you can use the following command to deploy with Kustomize: +>`kustomize build overlays/production | kubectl apply -f` + +## Create the Production Environment Pipeline + +Likewise, this pipeline will have two stages: clone and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-prod-pipeline.png" +url="/images/examples/deployments/k8s-kustomize-prod-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI and remember to replace cluster context for the kubectl command again with your own. Click Save and Run and it will automatically clone the project for you. + +`prod-codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/yaml-examples/examples/ + +version: "1.0" +# Stages can help you organize your steps in stages + +stages: + - clone + - deploy + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: clone + arguments: + repo: https://github.com/codefresh-contrib/kustomize-sample-app.git + git: github + revision: master + + deploy: + title: Deploying to Production using Kustomize... + type: freestyle + stage: deploy + working_directory: ${{clone}} + arguments: + image: codefresh/kubectl:1.14.9 + commands: + - kubectl config use-context anna-sandbox@codefresh-support + - kubectl apply -k overlays/production +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that: + - Uses kubectl to connect to our Kubernetes cluster we have integrated with Codefresh + - Using Kustomize (the -k flag), deploys the application as a production environment with the appropriate value for `MY_MYSQL_DB` as defined in our configMap + +>Note that if you are using kubectl prior to 1.14, you can use the following command to deploy with Kustomize: +>`kustomize build overlays/production | kubectl apply -f` + +## Verification + +After you run these pipelines, your deployments will be visible from the [Kubernetes dashboard]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/#accessing-the-kubernetes-dashboard). + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-dashboard.png" +url="/images/examples/deployments/k8s-kustomize-dashboard.png" +alt="Codefresh Kubernetes Deployments" +caption="Codefresh Kubernetes Deployments" +max-width="100%" +%} + +You can test that the application deployed correctly to both environments by accessing the endpoints: + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-staging-endpoint.png" +url="/images/examples/deployments/k8s-kustomize-staging-endpoint.png" +alt="Staging endpoint" +caption="Staging endpoint" +max-width="100%" +%} + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-prod-endpoint.png" +url="/images/examples/deployments/k8s-kustomize-prod-endpoint.png" +alt="Production endpoint" +caption="Production endpoint" +max-width="100%" +%} + + +## What to Read Next + +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Deployment options to Kubernetes]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes) +- [Running custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) +- [Deploy with Helm]({{site.baseurl}}/docs/yaml-examples/examples/helm/) diff --git a/_docs/example-catalog/docker-swarm.md b/_docs/example-catalog/docker-swarm.md new file mode 100644 index 00000000..3075f406 --- /dev/null +++ b/_docs/example-catalog/docker-swarm.md @@ -0,0 +1,227 @@ +--- +title: "Docker SWARM" +description: "How to deploy to Docker Swarm with Codefresh" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/docker-swarm/ + - /docs/deploy-to-docker-swarm/ + - /docs/deploy-your-containers/docker-swarm/ +toc: true +--- + +Codefresh can easily deploy your application to [Docker Swarm](https://docs.docker.com/engine/swarm/) using [Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/). + +You will need to provide: + +1. The `docker-stack.yml` that contains the definition of the application +1. The host where your Docker Swarm is running +1. An SSH key that Codefresh can use to access remotely the Docker Swarm host +1. The stack name that will be used once the application is deployed + +All this information will be passed to the pipeline in the form of build parameters. + + +## Example application + +An example Docker Swarm application can be found at [https://github.com/codefreshdemo/example-voting-app](https://github.com/codefreshdemo/example-voting-app) + +To launch it locally you need to download [Docker](https://www.docker.com/products/overview). If you are on Mac or Windows, [Docker Compose](https://docs.docker.com/compose) will be automatically installed. On Linux, make sure you have the latest version of [Compose](https://docs.docker.com/compose/install/). + + +Run in this root directory: + +{% highlight bash %} +{% raw %} + +docker-compose up + +{% endraw %} +{% endhighlight %} + +The app will be running at [http://localhost:5000](http://localhost:5000), and the results will be at [http://localhost:5001](http://localhost:5001). + +Alternately, if you want to run it on a Docker Swarm, first make sure you have a swarm. If you don't, run: + +{% highlight bash %} +{% raw %} + +docker swarm init + +{% endraw %} +{% endhighlight %} + +Once you have your swarm, in this directory run: + +{% highlight bash %} +{% raw %} + +docker stack deploy --compose-file docker-stack.yml vote + +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_warning}} +The swarm master must have Python installed. +{{site.data.callout.end}} + +## Deploy to Remote Swarm with Codefresh + +First you need to setup the following environment variables in your Codefresh pipeline + +{: .table .table-bordered .table-hover} +| `RDOCKER_HOST` | remote Docker swarm master machine, accessible over SSH (for example, ubuntu@ec2-public-ip) | +| `STACK_NAME` | is new Docker stack name (use \"vote\", for example) | +| `SSH_KEY` | private SSH key, used to access Docker swarm master machine | +| `SPLIT_CHAR` | split character, you've used to replace `newline` in SSH key. Recommendation: use `,` (`comma` character). | + +The `SSH_KEY` variable has the contents of the [SSH key](https://www.ssh.com/ssh/public-key-authentication) that can access the Docker swarm host. Currently in order to pass SSH key through Codefresh UI, you need to convert it to single line string (replacing `newline` with `comma`), like this: + +{% highlight bash %} +{% raw %} +SSH_KEY=$(cat ~/.ssh/my_ssh_key_file | tr '\n' ',') +{% endraw %} +{% endhighlight %} + +The `SPLIT_CHAR` variable should hold the replacement character that was used for the SSH key (in the example above it is the comma character) + +{% include image.html +lightbox="true" +file="/images/2f1884a-codefresh_env_vars.png" +url="/images/2f1884a-codefresh_env_vars.png" +alt="Docker Swarm build parameters" +caption="Docker Swarm build parameters" +max-width="70%" +%} + + +## Deploy to Docker Swarm with a YML step + +Once all the variables are set you can use the following [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) to deploy to your cluster. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} + +deploy_to_swarm: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + commands: + - rdocker ${{RDOCKER_HOST}} docker stack deploy --compose-file docker-stack.yml ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} + when: + branch: + only: + - master + +{% endraw %} +{% endhighlight %} + +You can also pass custom credentials like this: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} + +deploy_to_swarm: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + commands: + - rdocker ${{RDOCKER_HOST}} docker login ${{MY_REGISTRY}} -u ${{MY_REGISTRY_USER}} -p ${{MY_REGISTRY_PASSWORD}} \&\& docker stack deploy --compose-file docker-compose.yml --with-registry-auth ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} + when: + branch: + only: + - master +{% endraw %} +{% endhighlight %} + + + + + + +## Create a CI/CD pipeine for Docker swarm + +Here is the full pipeline: + +{% include +image.html +lightbox="true" +file="/images/examples/docker-swarm/docker-swarm-pipeline.png" +url="/images/examples/docker-swarm/docker-swarm-pipeline.png" +alt="Docker Swarm pipeline" +caption="Docker Swarm pipeline" +max-width="100%" +%} + +And here is the pipeline definition: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/example-voting-app' + revision: master + git: github-1 + MyResultDockerImage: + title: Building Result Docker Image + stage: build + type: build + image_name: resultApp + working_directory: ./result/ + tag: master + dockerfile: Dockerfile + MyVoteDockerImage: + title: Building Vote Docker Image + stage: build + type: build + image_name: voteApp + working_directory: ./vote/ + tag: master + dockerfile: Dockerfile + MyWorkerDockerImage: + title: Building Worker Docker Image + stage: build + type: build + image_name: workedApp + working_directory: ./worker/ + tag: master + dockerfile: Dockerfile + DeployToSwarmNow: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + stage: deploy + commands: + - rdocker ${{RDOCKER_HOST}} docker login ${{MY_REGISTRY}} -u ${{MY_REGISTRY_USER}} -p ${{MY_REGISTRY_PASSWORD}} \&\& docker stack deploy --compose-file docker-compose.yml --with-registry-auth ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} +{% endraw %} +{% endhighlight %} + +The values of `MY_REGISTRY`, `MY_REGISTRY_USER` and `MY_REGISTRY_PASSWORD` depend upon the type of [your connected registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/). + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + + + + + + + diff --git a/_docs/example-catalog/dotnet.md b/_docs/example-catalog/dotnet.md new file mode 100644 index 00000000..9862e0c6 --- /dev/null +++ b/_docs/example-catalog/dotnet.md @@ -0,0 +1,115 @@ +--- +title: "C# on .NET Core" +description: "How to build a C# project in Codefresh" +group: learn-by-example +toc: true +--- + +Codefresh can work with any .NET core application very easily as there are official [Docker images from Microsoft](https://hub.docker.com/_/microsoft-dotnet-core). + +## The example C# project + +You can see the example project at [https://github.com/dotnet-architecture/eShopOnWeb](https://github.com/dotnet-architecture/eShopOnWeb). The repository contains a C# Web project with 3 kinds of tests. It has different tags for each version of .NET Core and has + +* a `docker-compose.yml` file for local development +* a `tests` directory with all types of tests +* a Dockerfile at `/src/Web` + +There are also previous releases at [https://github.com/dotnet-architecture/eShopOnWeb/releases](https://github.com/dotnet-architecture/eShopOnWeb/releases). + +### Create a CI pipeline for C# applications + +Creating a CI/CD pipeline for C# is very easy, because Codefresh can run any SDK image version that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/dotnet/dotnetcore-pipeline.png" +url="/images/learn-by-example/dotnet/dotnetcore-pipeline.png" +alt="Compiling a C# application in a pipeline" +caption="Compiling a C# application in a pipeline" +max-width="80%" +%} + +Here is the full pipeline that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'dotnet-architecture/eShopOnWeb' + revision: 'netcore3.0' + git: github-1 + my_unit_tests: + title: Unit tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/UnitTests/' + commands: + - dotnet test + my_integration_tests: + title: Integration tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/IntegrationTests/' + commands: + - dotnet test + my_functional_tests: + title: Fuctional tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/FunctionalTests/' + commands: + - dotnet test + my_app_docker_image: + title: Building Docker Image + type: build + stage: build + image_name: dotnetcore-eshop + working_directory: ./ + tag: latest + dockerfile: src/Web/Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline: + +1. clones the source code +1. Uses the official `mcr.microsoft.com/dotnet/core/sdk:3.0` image to run unit/integration/functional tests in 3 different folders +1. Builds the application docker image using the root folder as Docker context but with the Dockerfile located at `./src/Web` + +You can see the resulting image in the [image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images): + +{% include image.html +lightbox="true" +file="/images/learn-by-example/dotnet/dotnetcore-image.png" +url="/images/learn-by-example/dotnet/dotnetcore-image.png" +alt="Building a .NET core docker image" +caption="Building a .NET core docker image" +max-width="80%" +%} + + + + +## What to read next + +* [C/C++ examples]({{site.baseurl}}/docs/learn-by-example/cc/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + + + + + + diff --git a/_docs/example-catalog/elastic-beanstalk.md b/_docs/example-catalog/elastic-beanstalk.md new file mode 100644 index 00000000..3df5a510 --- /dev/null +++ b/_docs/example-catalog/elastic-beanstalk.md @@ -0,0 +1,137 @@ +--- +title: "Elastic Beanstalk" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/elastic-beanstalk/ + - /docs/deploy-your-containers/elastic-beanstalk/ +toc: true +--- + +## Deployment to Elastic Beanstalk + +{:.text-secondary} +### Prerequisites + +- Configured Application in Elastic Beanstalk service
+ See: [http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html){:target="_blank"} + +{:.text-secondary} +### Deployment with Codefresh +- Add encrypted environment variables for AWS credentials: + * `AWS_ACCESS_KEY_ID` + * `AWS_SECRET_ACCESS_KEY` + +- Provide the following environment variables: + * `AWS_REGION` + * `AWS_ENV_NAME` + * `AWS_VERSION` + * `AWS_BRANCH` + +{% include +image.html +lightbox="true" +file="/images/bcf4a57-codefresh_eb_env_vars.png" +url="/images/bcf4a57-codefresh_eb_env_vars.png" +alt="codefresh_eb_env_vars.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +{% raw %} +The ``${{AWS_VERSION}}`` of application you can find in the Elastic Beanstalk service. +{% endraw %} +{{site.data.callout.end}} + +{% include +image.html +lightbox="true" +file="/images/c4e5ea2-codefresh_eb_version_label.png" +url="/images/c4e5ea2-codefresh_eb_version_label.png" +alt="codefresh_eb_version_label.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +{% raw %} +The ``${{AWS_ENV_NAME}}`` of application you can find in the Elastic Beanstalk service. +{% endraw %} +{{site.data.callout.end}} + +{% include +image.html +lightbox="true" +file="/images/f326437-codefresh_eb_environment.png" +url="/images/f326437-codefresh_eb_environment.png" +alt="codefresh_eb_environment.png" +max-width="40%" +%} + +Add the following step to codefresh.yml: + + `deploy_step` +{% highlight yaml %} +{% raw %} +deploy-elastic-beanstalk: + fail-fast: false + image: garland/aws-cli-docker:latest + commands: + - sh -c "aws configure set region '${{AWS_REGION}}' && aws elasticbeanstalk update-environment --environment-name '${{AWS_ENV_NAME}}' --version-label '${{AWS_VERSION}}' " + when: + condition: + all: + masterBranch: "'${{CF_BRANCH}}' == '${{AWS_BRANCH}}'" +{% endraw %} +{% endhighlight %} + +{:.text-secondary} +### Deployment Flow +- Go to the Elastic Beanstalk service and create an application and environment. + + +{% include +image.html +lightbox="true" +file="/images/0cd9b90-codefresh_eb_environment.png" +url="/images/0cd9b90-codefresh_eb_environment.png" +alt="codefresh_eb_environment.png" +max-width="40%" +%} + +- Perform the following commands from root of your project: + * eb init + * eb create {% raw %}`${{AWS_ENV_NAME}}`{% endraw %} + +{{site.data.callout.callout_info}} +{% raw %} +##### Note: + +If you don't have awsebcli - install EB CLI [http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html){:target="_blank"}. +{% endraw %} +{{site.data.callout.end}} + +{% include +image.html +lightbox="true" +file="/images/c1335ec-codefresh_eb_health.png" +url="/images/c1335ec-codefresh_eb_health.png" +alt="codefresh_eb_health.png" +max-width="40%" +%} + +- Add this repository to Codefresh, provide the necessary environments variables and build this service + +{% include +image.html +lightbox="true" +file="/images/648e324-codefresh_eb_cf_step_deploy.png" +url="/images/648e324-codefresh_eb_cf_step_deploy.png" +alt="codefresh_eb_cf_step_deploy.png" +max-width="40%" +%} + +## Example + +* [cf-example-deploy-elasticbeanstalk](https://github.com/codefreshdemo/cf-example-deploy-elasticbeanstalk){:target="_blank"} + diff --git a/_docs/example-catalog/examples.md b/_docs/example-catalog/examples.md new file mode 100644 index 00000000..d1d968ca --- /dev/null +++ b/_docs/example-catalog/examples.md @@ -0,0 +1,119 @@ +--- +title: "CI/CD pipeline examples" +description: "A collection of examples for Codefresh pipelines" +group: yaml-examples +redirect_from: + - /docs/examples-v01/ + - examples.html + - /docs/catalog-examples/ + - /docs/examples/ + - /docs/codefresh-yaml-examples/ + - /docs/codefresh-yaml/codefresh-yaml-examples/ +toc: true +--- +Codefresh enables you to define the steps of your pipeline in a [YAML file]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/). By default, the file is named `codefresh.yml`, and is located in the root directory of the repository. + +## Programming-language specific examples + +Codefresh is agnostic as far as programming languages are concerned. All major programming languages are supported: + +- [Go Web App]({{site.baseurl}}/docs/example-catalog/golang/golang-hello-world/) or [Go CLI]({{site.baseurl}}/docs/example-catalog/golang/goreleaser) +- [Spring Java app with Maven]({{site.baseurl}}/docs/example-catalog/java/spring-boot-2/) or [Gradle]({{site.baseurl}}/docs/example-catalog/java/gradle/). Also how to [upload JAR to Nexus/Artifactory]({{site.baseurl}}/docs/example-catalog/java/publish-jar/) +- Node [Express.js App]({{site.baseurl}}/docs/example-catalog/nodejs/lets-chat/) or [React.js App]({{site.baseurl}}/docs/example-catalog/nodejs/react/) +- [Php App]({{site.baseurl}}/docs/example-catalog/php) +- [Python Django App]({{site.baseurl}}/docs/example-catalog/python/django/) +- [Ruby On Rails App]({{site.baseurl}}/docs/example-catalog/ruby/) +- [C]({{site.baseurl}}/docs/example-catalog/cc/c-make/) or [C++]({{site.baseurl}}/docs/example-catalog/cc/cpp-cmake) +- [Rust]({{site.baseurl}}/docs/example-catalog/rust/) +- [C# .NET core]({{site.baseurl}}/docs/example-catalog/dotnet/) +- [Scala App]({{site.baseurl}}/docs/example-catalog/scala/scala-hello-world/) +- [Android (Mobile)]({{site.baseurl}}/docs/example-catalog/mobile/android/) + +## Source code checkout examples + +You can check out code from one or more repositories in any pipeline phase. Codefresh includes [built-in GIT integration]({{site.baseurl}}/docs/integrations/git-providers/) with all the popular GIT providers and can be used with [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) steps. + +- [Cloning Git repositories using the built-in integration]({{site.baseurl}}/docs/example-catalog/git-checkout/) +- [Cloning Git repositories using manual Git commands]({{site.baseurl}}/docs/example-catalog/git-checkout-custom/) +- [Checking out from Subversion, Perforce, Mercurial, etc ]({{site.baseurl}}/docs/example-catalog/non-git-checkout/) + +## Build/push examples + +Codefresh has native support for [building]({{site.baseurl}}/docs/pipelines/steps/build/) and [pushing]({{site.baseurl}}/docs/pipelines/steps/push/) Docker containers. +You can also compile traditional applications that are not Dockerized yet. + +- [Build an Image with the Dockerfile in root directory]({{site.baseurl}}/docs/example-catalog/build-an-image-dockerfile-in-root-directory/) +- [Build an Image by specifying the Dockerfile location]({{site.baseurl}}/docs/example-catalog/build-an-image-specify-dockerfile-location) +- [Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/build-an-image-from-a-different-git-repository) +- [Build and Push an Image]({{site.baseurl}}/docs/example-catalog/build-and-push-an-image) +- [Build an Image with build arguments]({{site.baseurl}}/docs/example-catalog/build-an-image-with-build-arguments) +- [Share data between steps]({{site.baseurl}}/docs/example-catalog/shared-volumes-between-builds) +- [Upload or download from a Google Storage Bucket]({{site.baseurl}}/docs/example-catalog/uploading-or-downloading-from-gs/) +- [Get Short SHA ID and use it in a CI process]({{site.baseurl}}/docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process) +- [Call a CD pipeline from a CI pipeline]({{site.baseurl}}/docs/example-catalog/call-child-pipelines) +- [Trigger a Kubernetes Deployment from a Dockerhub Push Event]({{site.baseurl}}/docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry/) + +## Unit and integration test examples + +Codefresh has support for both [unit]({{site.baseurl}}/docs/testing/unit-tests/) and [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) as well as [test reporting]({{site.baseurl}}/docs/testing/test-reports/). + +- [Run unit tests]({{site.baseurl}}/docs/example-catalog/run-unit-tests) +- [Run integration tests]({{site.baseurl}}/docs/example-catalog/run-integration-tests/) +- [Run integration tests with MongoDB]({{site.baseurl}}/docs/example-catalog/integration-tests-with-mongo/) +- [Run integration tests with MySQL]({{site.baseurl}}/docs/example-catalog/integration-tests-with-mysql/) +- [Run integration tests with PostgreSQL]({{site.baseurl}}/docs/example-catalog/integration-tests-with-postgres/) +- [Run integration tests with Redis]({{site.baseurl}}/docs/example-catalog/integration-tests-with-redis/) +- [Populate a database with existing data]({{site.baseurl}}/docs/example-catalog/populate-a-database-with-existing-data) + +- [Shared volumes of service from composition step for other yml steps]({{site.baseurl}}/docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps) +- [Launch Composition]({{site.baseurl}}/docs/example-catalog/launch-composition) +- [Launch Composition and define Service Environment variables using a file]({{site.baseurl}}/docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file) +- [Run multiple kinds of unit tests using fan-in-fan-out parallel pipeline]({{site.baseurl}}/docs/example-catalog/fan-in-fan-out) + +## Code coverage examples + +- [Run coverage reports with Codecov]({{site.baseurl}}/docs/example-catalog/codecov-testing) +- [Run coverage reports with Coveralls]({{site.baseurl}}/docs/example-catalog/coveralls-testing) +- [Run coverage reports with Codacy]({{site.baseurl}}/docs/example-catalog/codacy-testing) + +## Secrets examples + +Codefresh can automatically export secret key-value pairs using the Vault plugin from the [Step Marketplace](https://codefresh.io/steps/step/vault). + +- [Vault secrets in the Pipeline]({{site.baseurl}}/docs/example-catalog/vault-secrets-in-the-pipeline) +- [Decryption with Mozilla SOPS]({{site.baseurl}}/docs/example-catalog/decryption-with-mozilla-sops) +- [GitOps with Bitnami sealed secrets]({{site.baseurl}}/docs/example-catalog/gitops-secrets) + +## Preview environment examples + +Codefresh can automatically launch environments (powered by Docker swarm) to [preview a Pull Reqest or feature]({{site.baseurl}}/docs/getting-started/on-demand-environments/). The definition of the environment can come from an [existing composition]({{site.baseurl}}/docs/testing/create-composition/), a docker-compose file or an inline YAML. Preview environments can be launched manually or [automatically from pipelines]({{site.baseurl}}/docs/pipelines/steps/launch-composition/). + +- [MongoDB preload data]({{site.baseurl}}/docs/example-catalog/import-data-to-mongodb/) +- [NodeJS + Angular2 + MongoDB]({{site.baseurl}}/docs/example-catalog/nodejs-angular2-mongodb/) +- [NGINX Basic Auth]({{site.baseurl}}/docs/example-catalog/secure-a-docker-container-using-http-basic-auth/) +- [Spring Boot + Kafka + Zookeeper]({{site.baseurl}}/docs/example-catalog/spring-boot-kafka-zookeeper/) +- [Web terminal]({{site.baseurl}}/docs/example-catalog/web-terminal/) + +## Deployment examples + +Codefresh can deploy to any platform such as VMs, FTP/SSH/S3 sites, app servers, but of course it has great support for [Kubernetes clusters]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes/) and [Helm releases]({{site.baseurl}}/docs/new-helm/helm-releases-management/): + +- [Deploy to a VM with packer]({{site.baseurl}}/docs/example-catalog/packer-gcloud/) +- [Deploy to a VM with FTP]({{site.baseurl}}/docs/example-catalog/transferring-php-ftp) +- [Deploy to Tomcat using SCP]({{site.baseurl}}/docs/example-catalog/deploy-to-tomcat-via-scp) +- [Deploy Demochat to a Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/codefresh-kubernetes-integration-demochat-example/) +- [Use kubectl as part of freestyle step]({{site.baseurl}}/docs/example-catalog/use-kubectl-as-part-of-freestyle-step) +- [Deploy with Kustomize]({{site.baseurl}}/docs/example-catalog/deploy-with-kustomize) +- [Deploy with Helm]({{site.baseurl}}/docs/example-catalog/helm) +- [Deploy with Terraform]({{site.baseurl}}/docs/example-catalog/terraform) +- [Deploy with Pulumi]({{site.baseurl}}/docs/example-catalog/pulumi) +- [Deploy to Nomad]({{site.baseurl}}/docs/example-catalog/nomad) +- [Deploy to Heroku]({{site.baseurl}}/docs/example-catalog/deploy-to-heroku/) +- [Deploy to Docker swarm]({{site.baseurl}}/docs/example-catalog/docker-swarm/) +- [Deploy to Elastic Beanstalk]({{site.baseurl}}/docs/example-catalog/elastic-beanstalk/) +- [Deploy to Amazon ECS/Fargate]({{site.baseurl}}/docs/example-catalog/amazon-ecs/) + +## Notification examples + +- [Send notification to Slack]({{site.baseurl}}/docs/example-catalog/sending-the-notification-to-slack) +- [Send notification to Jira]({{site.baseurl}}/docs/example-catalog/sending-the-notification-to-jira) diff --git a/_docs/example-catalog/fan-in-fan-out.md b/_docs/example-catalog/fan-in-fan-out.md new file mode 100644 index 00000000..59d9775d --- /dev/null +++ b/_docs/example-catalog/fan-in-fan-out.md @@ -0,0 +1,206 @@ +--- +title: "Fan-out-fan-in Pipeline" +description: "Use parallel mode to fan-in and fan-out your step dependencies" +group: yaml-examples +sub_group: examples +toc: true +--- + +In pipelines, the concept of fan-in/fan-out is depicted in the diagram below. This pipeline offers parallel sub-flows in a single pipeline. Fan-out refers to spreading a task to multiple destinations in parallel, and fan-in is the opposite, where we spread multiple different tasks to the same destination. + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/parallel-pipeline-examples.png" +url="/images/examples/unit-tests/parallel-pipeline-examples.png" +alt="parallel pipeline diagraam" +caption="Parallel Mode Diagram" +max-width="100%" +%} + +As you can see by the diagram, Step1 fans out to Step2 and Step4 (which run in parallel), while Step3 and Step4 fan-in to Step5. + +You can achieve parallelism in your Codefresh pipelines by using the following: + +- Simple parallel jobs ([inserting parallel steps into a sequential pipeline]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#inserting-parallel-steps-in-a-sequential-pipeline)) +- [Full parallel mode]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#parallel-pipeline-mode) +- Fan-out/fan-in parallel pipelines, as covered here + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) + +## The Example Project + +You can find the example Spring boot application on [GitHub](https://github.com/codefresh-contrib/fan-out-fan-in-sample-app.git). It is a simple Hello World application that has several different types of tests we will be using to run using Codefresh's parallel mode. + +## Create the Pipeline + +Our pipeline will have five stages: setup, start, web-tests, smoke, and end: + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/fan-in-fan-out-pipeline.png" +url="/images/examples/unit-tests/fan-in-fan-out-pipeline.png" +alt="fan-in-fan-out UI pipeline view" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +mode: parallel +stages: +- setup +- start +- web-tests +- smoke +- end +steps: + Clone: + title: Cloning main repository... + stage: setup + type: git-clone + arguments: + repo: codefresh-contrib/fan-out-fan-in-sample-app + git: github + revision: master + Build_image: + title: Building Docker Image... + type: build + stage: setup + working_directory: ${{Clone}} + arguments: + image_name: spring-backend + tag: latest + dockerfile: Dockerfile + when: + steps: + - name: Clone + on: + - success + Step1: + title: Running unit tests... + stage: start + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="unit" test + when: + steps: + - name: Build_image + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step2: + title: Running web mock test... + stage: web-tests + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="web-mock" test + when: + steps: + - name: Step1 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step3: + title: Running smoke test... + stage: smoke + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="smoke" test + when: + steps: + - name: Step2 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step4: + title: Running web layer tests... + stage: web-tests + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="web-layer" test + when: + steps: + - name: Step1 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step5: + title: Running integration tests... + stage: end + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="integration" test + when: + steps: + - name: Step3 + on: + - success + - name: Step4 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 +{% endraw %} +{% endhighlight %} + +Note the special use of `mode: parallel` declared at the root of our yaml. This syntax makes the pipeline use the full parallel mode. +The order of your build steps doesn't matter in this case, each step is executed according to its [conditionals](https://codefresh.io/docs/docs/codefresh-yaml/conditional-execution-of-steps/). + +- Step1 (unit tests) fans out to Step2 and Step4 (web tests), which run in parallel +- Step3 (smoke tests) does not execute until Step2 is completed +- Step3 and Step4 fan in to the final step, Step5 (integration tests) + +This pipeline consists of the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) that builds the cloned source code into a Docker image +3. 5 [freestyle steps]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that: + - Runs unit tests according to their respective @Tags + - Uses the image built in the second step as a [Service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) + +## What to Read Next + + - [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) + - [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + - [Service Containers]({{site.baseurl}}//docs/codefresh-yaml/service-containers/) + - [Parallel Mode]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/#parallel-pipeline-mode) diff --git a/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md b/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md new file mode 100644 index 00000000..bc96d9f6 --- /dev/null +++ b/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md @@ -0,0 +1,69 @@ +--- +title: "Get Short SHA ID and Use it in a CI Process" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/how-to-guides/ + - /docs/how-get-first-8-digits-of-sha/ +toc: true +old_url: /docs/how-get-first-8-digits-of-sha +--- + +## Get the short SHA ID +Put the following variable in your script + +{{site.data.callout.callout_info}} +{% highlight text %} +{% raw %} +${{CF_SHORT_REVISION}} +{% endraw %} +{% endhighlight %} +{{site.data.callout.end}} + +## Use the SHA ID in a tag + +{{site.data.callout.callout_info}} +{% highlight text %} +{% raw %} +tag: ${{CF_SHORT_REVISION}} +{% endraw %} +{% endhighlight %} +{{site.data.callout.end}} + +## YAML example + +{% highlight yaml %} +{% raw %} +step-name: + type: build + description: Free text description + working-directory: ${{clone-step-name}} + dockerfile: path/to/Dockerfile + image-name: owner/new-image-name + tag: ${{CF_SHORT_REVISION}} + build-arguments: + - key=value + fail-fast: false +{% endraw %} +{% endhighlight %} + +## Result in [hub.docker](https://hub.docker.com){:target="_blank"} + +{% include image.html +lightbox="true" +file="/images/b694c19-2016-10-18_17-42-38.png" +url="/images/b694c19-2016-10-18_17-42-38.png" +alt="2016-10-18_17-42-38.png" +max-width="40%" +%} + +## Result in Codefresh + +{% include image.html +lightbox="true" +file="/images/de17013-2016-10-18_17-49-22.png" +url="/images/de17013-2016-10-18_17-49-22.png" +alt="2016-10-18_17-49-22.png" +max-width="40%" +%} diff --git a/_docs/example-catalog/git-checkout-custom.md b/_docs/example-catalog/git-checkout-custom.md new file mode 100644 index 00000000..c7e01e10 --- /dev/null +++ b/_docs/example-catalog/git-checkout-custom.md @@ -0,0 +1,105 @@ +--- +title: "Using Custom Git commands" +description: "Clone manually git repositories" +group: yaml-examples +sub_group: git +redirect_from: + - /docs/git-clone-private-repository-using-freestyle-step/ + - /docs/yaml-examples/examples/git-clone-private-repository-using-freestyle-step/ +toc: true +--- + +>Notice that running git commands manually is an advanced technique. For most use cases you should use the [Native Git checkout]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) offered by Codefresh. + +If you want to do complex cloning, you can still use custom clone commands in a freestyle step. Notice however that in this case +you lose the native Codefresh integration such as git authentication and automatic workdir setup. Use custom clone commands only as a last resort. + + +## Cloning with the git executable + +It is very easy to run custom git commands in a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). Pass any parameters to the git clone step as you would pass them on your local workstation. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Performing swallow clone + image: alpine/git:latest + commands: + - rm -rf ruby-on-rails-sample-app + - git clone --depth 1 https://github.com/codefresh-contrib/ruby-on-rails-sample-app.git + PrintFileList: + title: 'Listing files' + image: alpine:latest + working_directory: './ruby-on-rails-sample-app' + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +Notice the `rm` command before the clone step. This makes sure that every time the pipeline will run the `git clone` step will happen in an empty directory. Otherwise the `git clone` command will fail (git will refuse to clone on an existing directory). + +You can enter your own git username/password or [reuse the credentials]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/#reuse-a-git-token-from-codefresh-integrations) from the Codefresh integration. + +## Running Git commands manually + +Once you understand that you can run manually git commands in Codefresh pipelines, it is easy to see that any git workflow is possible. +Here is an example where an application is packaged in a Docker container, after merging `master` to a specific branch. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Performing swallow clone + image: alpine/git:latest + commands: + - rm -rf example_nodejs_postgres + - git clone https://github.com/kostis-codefresh/example_nodejs_postgres + - cd example_nodejs_postgres + - git checkout experiment1 + - git merge master + - git status + myDockerImage: + title: 'BuildingDockerImage' + type: build + dockerfile: Dockerfile + working_directory: './example_nodejs_postgres' + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +If there are any errors with the merge the pipeline will automatically fail. Codefresh will automatically stop any pipeline that shows an error in a step. + +## Other forms of cloning + +There is nothing special about running GIT it in a freestyle step. In fact, you can checkout code with any other command that you would run locally in your terminal. + +Here is an example with Golang. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Download example + image: golang:1.11-alpine + commands: + - apk add --no-cache git + - go get github.com/golang/example/hello +{% endraw %} +{% endhighlight %} + +If you run this pipeline you will see git used as part of the `go get` mechanism. + +More examples such as using SSH keys and working with GIT submodules can be found in the [clone step documentation]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). + + +## What to read next + +* [Native Git checkout]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) +* [Native Git integration]({{site.baseurl}}/docs/integrations/git-providers/) +* [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +* [Git Clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) diff --git a/_docs/example-catalog/git-checkout.md b/_docs/example-catalog/git-checkout.md new file mode 100644 index 00000000..e4de0cff --- /dev/null +++ b/_docs/example-catalog/git-checkout.md @@ -0,0 +1,204 @@ +--- +title: "Checking out Git repositories" +description: "Using the Codefresh native GIT integration" +group: yaml-examples +sub_group: examples +toc: true +--- + +Codefresh has native support for GIT repositories and Git triggers. First you need to setup a [GIT integration]({{site.baseurl}}/docs/integrations/git-providers/) (Your administrator might also have done this for you already). + +{% include image.html +lightbox="true" +file="/images/integrations/git/git-integrations.png" +url="/images/integrations/git/git-integrations.png" +alt="GIT integrations" +caption="GIT integrations" +max-width="70%" +%} + +You can add new integration for any cloud provider or even [on-premises]({{site.baseurl}}/docs/enterprise/behind-the-firewall/) ones. By default you will also have a provider setup if you used one for Codefresh signup (GitHub, GitLab or Bitbucket). + +For each Git Integration, make sure that you note down its name, as you will use in your pipeline inside a [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step. + + +## Cloning a specific repository + +The simplest way to clone using your git provider is by specifying the exact repository details. +Here is a pipeline that clones a git repository and creates a Docker image from a Dockerfile: + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: master + git: github-1 + myDockerImage: + title: 'Building My Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +This syntax is very simple to use, but it has the disadvantage that ties your pipeline to a specific repository. This makes +the pipeline impossible to re-use among different micro-services (that are built in a similar manner). + +## Cloning the triggered repository (recommended) + +The proper way to use git-clone steps is to make them trigger specific. Instead of hard-coding the git repository that is checked-out, it is best to checkout the same one that [triggered the pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/). This is what you want in most scenarios anyway. + +This can be achieved by using Codefresh [variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) to refer to the trigger. +Here is the same pipeline as before, written in a generic way: + +`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: github-1 + myDockerImage: + title: 'Building My Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: ${{CF_BRANCH_TAG_NORMALIZED}} +{% endraw %} +{% endhighlight %} + +The big advantage of this pipeline is that it can be reused for *ALL* your projects that follow the same pattern of having a Dockerfile in the root of the git repository. + +{% include image.html +lightbox="true" +file="/images/examples/checkout/add-new-microservice.png" +url="/images/examples/checkout/add-new-microservice.png" +alt="Reusing a pipeline between microservices" +caption="Reusing a pipeline between microservices" +max-width="50%" +%} + +Thus you can have a single pipeline and when you want to enable it for a new micro-service you can simply add a new [git trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) for it. + +You still run the pipeline manually if you wish. In this case you will be asked which trigger you want to "simulate" so that the variable pipelines are correctly replaced by Codefresh. + +{% include image.html +lightbox="true" +file="/images/examples/checkout/simulate-trigger.png" +url="/images/examples/checkout/simulate-trigger.png" +alt="Simulating a GIT trigger" +caption="Simulating a GIT trigger" +max-width="50%" +%} + +This is the recommended way of creating re-usable pipelines in Codefresh. + +## Cloning a repository 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). + + +## Working inside the cloned directory + +Normally each [pipeline step]({{site.baseurl}}/docs/codefresh-yaml/steps/) in Codefresh can be named as you want. Specifically, for the git-clone step however the name `main_clone` is special. + +If you name your clone step as `main_clone` the Codefresh will automatically change the working directory for all the next (non git-clone) pipeline steps, to be the same as the project that was just 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). + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/checkout.png" +url="/images/pipeline/introduction/checkout.png" +alt="Checkout structure" +caption="Checkout structure" +max-width="50%" +%} + +This is probably what you want anyway, so make sure that you name your git-clone steps as `main_clone`. If you use any other name, then the working folder will be the parent of the checked-out project which is the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) at `/codefresh/volume`. + +If you have more then one clone steps in a pipeline it is recommended to define the working directory explicitly (see next example), instead +of depending on the `main_clone` naming convention, which is best used in pipelines with a single clone step. + +## Cloning multiple repositories + +You can use as many clone steps as you want and at any position in the pipeline. They don't have to be the first step. + +Here is an example where two repositories are checked out and two docker images are then built. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + checkoutApp1: + title: 'Cloning first repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: experiment1 + git: github + myFirstDockerImage: + title: 'Building First Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-nodejs-image + tag: from-develop-branch + working_directory: './example_nodejs_postgres' + checkoutApp2: + title: 'Cloning second repository...' + type: git-clone + repo: kostis-codefresh/trivial-go-web + revision: master + git: github + mySecondDockerImage: + title: 'Building Second Docker Image' + type: build + dockerfile: Dockerfile + working_directory: './trivial-go-web' + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +Notice that in this case the git-clone steps are **not** named `main_clone` and therefore we specify exactly what is the working directory for each one. + + +## What to read next + +* [Git integrations]({{site.baseurl}}/docs/integrations/git-providers/) +* [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) +* [Git Clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +* [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +* [Custom git commands]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout-custom/) \ No newline at end of file diff --git a/_docs/example-catalog/gitops-secrets.md b/_docs/example-catalog/gitops-secrets.md new file mode 100644 index 00000000..84c05726 --- /dev/null +++ b/_docs/example-catalog/gitops-secrets.md @@ -0,0 +1,232 @@ +--- +title: "Using secrets with GitOps" +description: "Store secrets in Git with Bitnami sealed secrets" +group: yaml-examples +sub_group: examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A Kubernetes cluster +- The [Codefresh GitOps agent]({{site.baseurl}}/docs/integrations/argocd/) installed on the cluster + +## Using the Bitnami Sealed secrets controller + +If you follow [GitOps](https://codefresh.io/gitops/), then you should already know that everything should be placed under source control, and Git is to be used as the single source of truth. + +This presents a challenge with secrets that are needed by the application, as they must never be stored in Git in clear text under any circumstance. + +To solve this issue, we can use the [Bitnami Sealed secrets controller](https://github.com/bitnami-labs/sealed-secrets). This is a Kubernetes controller +that can be used to encrypt/decrypt your application secrets in a secure way. + +The order of events is the following: + +1. You install the Bitnami Sealed secrets controller in the cluster. It generates a public and private key. The private key stays in the cluster and never gets out +1. You take a raw secret and use the `kubeseal` utility to encrypt it. Encryption happens with the public key of the cluster that you can give to anybody. +1. The encrypted secrets are stored in Git. There are safe to be committed and nobody can decrypt them without direct access to the cluster +1. During runtime you deploy the sealed secret like any other Kubernetes manifest. The controller converts them to [plain Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/) on the fly using the private key of the cluster +1. Your application reads the secrets like any other Kubernetes secret. Your application doesn't need to know anything about the sealed secrets controller or how the encryption decryption works. + + +To use the controller first install it in your cluster + +``` +helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets +helm repo update +helm install sealed-secrets-controller sealed-secrets/sealed-secrets +``` + +By default the controller will be installed at the `kube-system` namespace. The namespace +and release name are important, since if you change the defaults, you need to set them up +with `kubeseal` as well as you work with secrets + +Download the `kubeseal` CLI. + +``` +wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.16.0/kubeseal-linux-amd64 -O kubeseal +sudo install -m 755 kubeseal /usr/local/bin/kubeseal +``` + +## The example application + +You can find the example project at [https://github.com/codefresh-contrib/gitops-secrets-sample-app](https://github.com/codefresh-contrib/gitops-secrets-sample-app). + +It is a web application that prints out several secrets which are [read from the filesystem](https://github.com/codefresh-contrib/gitops-secrets-sample-app/blob/main/settings.ini): + +`settings.ini` +```ini +[security] +# Path to key pair +private_key = /secrets/sign/key.private +public_key= /secrets/sign/key.pub + +[paypal] +paypal_url = https://development.paypal.example.com +paypal_cert=/secrets/ssl/paypal.crt + +[mysql] +db_con= /secrets/mysql/connection +db_user = /secrets/mysql/username +db_password = /secrets/mysql/password +``` + +The application itself knows nothing about Kubernetes secrets, mounted volumes or any other cluster resource. It only reads its own filesystem at `/secrets` + +This folder is populated inside the pod with [secret mounting](https://github.com/codefresh-contrib/gitops-secrets-sample-app/blob/main/manifests/deployment.yml): + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitops-secrets-deploy +spec: + replicas: 1 + selector: + matchLabels: + app: gitops-secrets-app + template: + metadata: + labels: + app: gitops-secrets-app + spec: + containers: + - name: gitops-secrets-app + image: docker.io/kostiscodefresh/gitops-secrets-sample-app:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + volumeMounts: + - name: mysql + mountPath: "/secrets/mysql" + readOnly: true + - name: paypal + mountPath: "/secrets/ssl" + readOnly: true + - name: sign-keys + mountPath: "/secrets/sign/" + readOnly: true + livenessProbe: + httpGet: + path: /health + port: 8080 + readinessProbe: + httpGet: + path: /health + port: 8080 + volumes: + - name: mysql + secret: + secretName: mysql-credentials + - name: paypal + secret: + secretName: paypal-cert + - name: sign-keys + projected: + sources: + - secret: + name: key-private + - secret: + name: key-public + +``` + +This way there is a clear separation of concerns. + + + +You can find the secrets themselves at [https://github.com/codefresh-contrib/gitops-secrets-sample-app/tree/main/never-commit-to-git/unsealed_secrets](https://github.com/codefresh-contrib/gitops-secrets-sample-app/tree/main/never-commit-to-git/unsealed_secrets). There are encoded with base64 so they are **NOT** safe to commit in Git. + +>Note that for demonstration reasons the Git repository contains raw secrets so that you can encrypt them yourself. In a production application the Git repository must only contain sealed/encrypted secrets + +## Preparing the secrets + +The critical point of this application is to encrypt all the secrets and place them in Git. +By default, the sealed secrets controller will encrypt a secret according to a specific namespace (this behavior is configurable) so you need to decide in advance what namespace wil host the application. + +Then encrypt all secrets as below: + +``` +kubectl create ns git-secrets +cd safe-to-commit/sealed_secrets +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/db-creds.yml > db-creds.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/key-private.yml > key-private.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/key-public.yml > key-public.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/paypal-cert.yml > paypal-cert.json +kubectl apply -f . -n git-secrets + +``` + +You now have encrypted your plain secrets. These files are safe to commit to Git. +You can see that they have been converted automatically to plain secrets with the command + +``` +kubectl get secrets -n git-secrets +``` + +## Deploying manually the application + +Note that the application requires all secrets to be present: + +``` +cd safe-to-commit/manifests +kubectl apply -f . -n git-secrets +``` + +You can now visit the application url to see how it has access to all the secrets. + + +## Deploying the application with Codefresh GitOps + +Of course the big advantage of having everything committed into Git, is the ability to adopt GitOps +for the whole application (including secrets). + +This means that you can simply [point Codefresh GitOps to your repository]({{site.baseurl}}/docs/integrations/argocd/#creating-argocd-applications) and have the application +automatically deploy in the cluster. + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/add-app.png" +url="/images/examples/sealed-secrets/add-app.png" +alt="Creating a GitOps application" +caption="Creating a GitOps application" +max-width="50%" +%} + +You can then see the application in the GitOps dashboard: + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/current-state.png" +url="/images/examples/sealed-secrets/current-state.png" +alt="GitOps dashboard" +caption="GitOps dashboard" +max-width="90%" +%} + +If you visit its URL you will +see the loading of secrets: + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/app-secrets.png" +url="/images/examples/sealed-secrets/app-secrets.png" +alt="Application using secrets" +caption="Application using secrets" +max-width="90%" +%} + + +>Note that for simplicity reasons the same Git repository holds both the application source code and its +manifests. In a real application you should have two Git repositories (one of the source code only and one of the manifests). + + +## What to Read Next + +- [Codefresh GitOps]({{site.baseurl}}/docs/ci-cd-guides/gitops-deployments/) +- [Using secrets]({{site.baseurl}}/docs/configure-ci-cd-pipeline/secrets-store/) +- [Secrets with Mozilla Sops]({{site.baseurl}}/docs/yaml-examples/examples/decryption-with-mozilla-sops/) +- [Vault Secrets in the Pipeline]({{site.baseurl}}/docs/yaml-examples/examples/vault-secrets-in-the-pipeline/) + diff --git a/_docs/example-catalog/golang/golang-hello-world.md b/_docs/example-catalog/golang/golang-hello-world.md new file mode 100644 index 00000000..665c43ab --- /dev/null +++ b/_docs/example-catalog/golang/golang-hello-world.md @@ -0,0 +1,268 @@ +--- +title: "Create a Docker image for GO" +description: "Using Codefresh pipelines" +group: learn-by-example +sub_group: golang +redirect_from: + - /docs/go/cf-example-golang-hello-world/ +toc: true +--- + +Codefresh can work with Go projects of any version using built-in modules or any other dependency mechanism. + +## The example golang project + +You can see the example project at [https://github.com/codefresh-contrib/golang-sample-app](https://github.com/codefresh-contrib/golang-sample-app). The repository contains a simple Golang web application including unit tests. There are 3 Dockerfiles available: + +* [Simple Dockerfile](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile) (with old Go version that requires `GOPATH` building) +* [Dockerfile with Go modules](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile.mod) (optimized for Docker caching) +* [Multi-stage Dockerfile](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile.multistage) (with Go modules and unit tests) + +Let's see these workflows in order. + +## Simple Docker image pipeline + +The most [simple pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh.yml) that you can create is just two [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/). A [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) to fetch the code and a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) to create a Docker image. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-golang-image + working_directory: ./ + tag: full + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Once you run this pipeline Codefresh will create a Docker image for the Golang application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-simple-pipeline.png" +url="/images/learn-by-example/golang/golang-simple-pipeline.png" +alt="Simple pipeline for Golang" +caption="Simple pipeline for Golang" +max-width="80%" +%} + +The big advantage of this workflow is that the Dockerfile you use can define any Go version and dependency tool. As long as the Dockerfile is self-contained (i.e. it compiles GO on its own), the pipeline will work as expected. + +In the example application, the simple (unoptimized) Dockerfile has an old Go version that still requires `GOPATH` folders. + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.10 + +# Set the Current Working Directory inside the container +WORKDIR $GOPATH/src/github.com/codefresh-contrib/go-sample-app + +# Copy everything from the current directory to the PWD (Present Working Directory) inside the container +COPY . . + +# Download all the dependencies +RUN go get -d -v ./... + +# Install the package +RUN go install -v ./... + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the executable +CMD ["go-sample-app"] +{% endraw %} +{% endhighlight %} + + +## Run unit tests as part of the pipeline + +If you want to run Go specific steps in your pipeline, you can use [freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) steps with any GO image that you want. If your GO application is using GO modules, this is even easier as you don't need to place the application into a specific GOPATH compliant directory first. + +This [pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh-gomod.yml) is running unit tests as a separate step and then builds the docker image. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - test + - build +steps: + main_clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: 'golang:1.12' + commands: + - go test -v + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: my-golang-image + working_directory: ./ + tag: modules + dockerfile: Dockerfile.mod +{% endraw %} +{% endhighlight %} + +If the unit tests fail, then the docker image will never be created (Codefresh automatically stops a pipeline when there is an error). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-ci-pipeline.png" +url="/images/learn-by-example/golang/golang-ci-pipeline.png" +alt="Golang pipeline with unit tests" +caption="Golang pipeline with unit tests" +max-width="80%" +%} + +Notice that in this case we have added module support in the Go application. The new Dockerfile is the following: + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.12-alpine + +RUN apk add --no-cache git + +# Set the Current Working Directory inside the container +WORKDIR /app/go-sample-app + +# We want to populate the module cache based on the go.{mod,sum} files. +COPY go.mod . +COPY go.sum . + +RUN go mod download + +COPY . . + +# Build the Go app +RUN go build -o ./out/go-sample-app . + + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the binary program produced by `go install` +CMD ["./out/go-sample-app"] +{% endraw %} +{% endhighlight %} + +The Dockerfile will also automatically take advantage of the Codefresh distributed docker cache. + + + +## Create a multi-stage Docker image for GO + +Especially with Go applications, the recommended way to create Docker images is with [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/). This makes the resulting Docker image as compact as possible. + +You can also embed unit tests in the Docker creation process, which guarantee the correctness of image (integration tests are best kept in the pipeline). + +Here is the new Dockerfile: + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.12-alpine AS build_base + +RUN apk add --no-cache git + +# Set the Current Working Directory inside the container +WORKDIR /tmp/go-sample-app + +# We want to populate the module cache based on the go.{mod,sum} files. +COPY go.mod . +COPY go.sum . + +RUN go mod download + +COPY . . + +# Unit tests +RUN CGO_ENABLED=0 go test -v + +# Build the Go app +RUN go build -o ./out/go-sample-app . + +# Start fresh from a smaller image +FROM alpine:3.9 +RUN apk add ca-certificates + +COPY --from=build_base /tmp/go-sample-app/out/go-sample-app /app/go-sample-app + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the binary program produced by `go install` +CMD ["/app/go-sample-app"] +{% endraw %} +{% endhighlight %} + +Codefresh has native support for multi-stage builds. The [pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh-multi-stage.yml) is the same as the first one with just two steps. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Multi-stage Image + type: build + image_name: my-golang-image + working_directory: ./ + tag: multi-stage + dockerfile: Dockerfile.multistage +{% endraw %} +{% endhighlight %} + +You should see a much smaller Docker image at the end. + + +## Viewing Docker images + +If you look at your [Docker registry dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images) created the advantages of the multi-stage build are very clear: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-image-size.png" +url="/images/learn-by-example/golang/golang-image-size.png" +alt="Creating different Docker images" +caption="Creating different Docker images" +max-width="80%" +%} + +We recommend using Go modules and multi-stage builds in your Go projects. + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/golang/goreleaser.md b/_docs/example-catalog/golang/goreleaser.md new file mode 100644 index 00000000..aa6e955d --- /dev/null +++ b/_docs/example-catalog/golang/goreleaser.md @@ -0,0 +1,121 @@ +--- +title: "Compile and release a Go application" +description: "Using Codefresh pipelines" +group: learn-by-example +sub_group: golang +toc: true +--- + +[Goreleaser](https://github.com/goreleaser/goreleaser) is a helper utility that allows you to easily create: + +* Binary packages for each OS/arch +* Archives +* GitHub releases +* Docker images +* Snap/RPM/deb/Homebrew + +for Go applications. + +Codefresh can also create Docker images on its own, but Goreleaser is still useful for the binary artifact creation capability. + + +## Run Goreleaser with docker + +You can see the example project at [https://github.com/codefresh-contrib/goreleaser-sample-app](https://github.com/codefresh-contrib/goreleaser-sample-app). The repository contains a simple Golang web application with a [goreleaser configuration](https://github.com/codefresh-contrib/goreleaser-sample-app/blob/master/.goreleaser.yml) + + +There is already a [Docker image for Goreleaser](https://hub.docker.com/r/goreleaser/goreleaser/) so it is very easy to use it in Codefresh pipeline. +In the most simple case you case run goreleaser in a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). + + `YAML` +{% highlight yaml %} +{% raw %} + ReleaseMyApp: + title: Creating packages + stage: release + image: 'goreleaser/goreleaser' + commands: + - goreleaser --snapshot --skip-publish --rm-dist +{% endraw %} +{% endhighlight %} + +More typically however you also need to provide a GitHub token so that GitHub releases are also available. There are two ways to do that. + + +## Create a CI pipeline that compiles/releases Go + +In most cases you want to just reuse the Git integration already defined in Codefresh. +This [pipeline](https://github.com/codefresh-contrib/goreleaser-sample-app/blob/master/codefresh.yml) is using the GitHub token from [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) in order to allow github access. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - release +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + stage: prepare + BuildMyApp: + title: Compiling go code + stage: build + image: 'golang:1.12' + commands: + - go build + GetGitToken: + title: Reading GitHub token + stage: release + image: codefresh/cli + commands: + - cf_export GITHUB_TOKEN=$(codefresh get context github-1 --decrypt -o yaml | yq -y .spec.data.auth.password) + ReleaseMyApp: + title: Creating packages + stage: release + image: 'goreleaser/goreleaser' + commands: + - goreleaser --rm-dist +{% endraw %} +{% endhighlight %} + +Note that GoReleaser [requires a GitHub API token](https://goreleaser.com/environment/) (`GITHUB_TOKEN`) with the `repo` scope to deploy artifacts to GitHub. +Here we use [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#exporting-environment-variables-from-a-freestyle-step) and the [codefresh CLI](https://codefresh-io.github.io/cli/) in order to ask Codefresh about the existing token (that was used in git integrations). In your case you need to change `github-1` with the name of your [GitHub integration]({{site.baseurl}}/docs/integrations/git-providers/). + +It also possible to pass a GITHUB_TOKEN directly in the pipeline, if you don't want to re-use the existing one. This is an alternative way of allowing Goreleaser to create GitHub releases. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/github-token.png" +url="/images/learn-by-example/golang/github-token.png" +alt="Passing a specific github token in the pipeline" +caption="Passing a specific github token in the pipeline" +max-width="70%" +%} + +You could also store the token in [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/). +Regardless of the way you choose to pass the GitHub token, the final step is to make sure that your pipeline is only executed for tag events. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/tags-only-trigger.png" +url="/images/learn-by-example/golang/tags-only-trigger.png" +alt="Run pipeline only on tag creation" +caption="Run pipeline only on tag creation" +max-width="80%" +%} + +This means that this pipeline will not run on normal commits. It is also possible to use [step conditionals]({{site.baseurl}}/docs/codefresh-yaml/conditional-execution-of-steps/) for more complex cases. + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/helm.md b/_docs/example-catalog/helm.md new file mode 100644 index 00000000..ba32dae4 --- /dev/null +++ b/_docs/example-catalog/helm.md @@ -0,0 +1,225 @@ +--- +title: "Deploy with Helm" +description: "Use Helm in a Codefresh pipeline" +group: yaml-examples +sub_group: examples +toc: true +--- + +[Helm](https://helm.sh/) is the package manager for Kubernetes. Codefresh has comprehensive support for Helm: + +* You get a free [built-in Helm repository]({{site.baseurl}}/docs/new-helm/managed-helm-repository/) with each Codefresh account. +* You can track your charts in the [Helm chart dashboard]({{site.baseurl}}/docs/new-helm/add-helm-repository/). +* You can view your deployments in your [Helm Release dashboard]({{site.baseurl}}/docs/new-helm/helm-releases-management/). +* You can view Helm releases in the [Environment dashsboard]({{site.baseurl}}/docs/deploy-to-kubernetes/environment-dashboard/). +* You can promote Helm releases in your [Helm promotion dashboard]({{site.baseurl}}/docs/new-helm/helm-environment-promotion/). +* You can add any external Helm repository on any other cloud provider. + +Codefresh also provides a [pipeline step]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) for deploying with Helm. + +For more insights on Helm charts see also our [Helm best practices]({{site.baseurl}}/docs/new-helm/helm-best-practices/) guide. + + +## The example Helm project + +You can see the example project at [https://github.com/codefresh-contrib/helm-sample-app](https://github.com/codefresh-contrib/helm-sample-app). The repository contains a simple Go application, a Dockerfile and an example chart. + + +## Prerequisites + +You need to have [added at least one Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/) in your Codefresh account. + +>Notice that if you still use Helm 2 you should also have installed the server side of Helm 2 (Tiller) using `helm init`. This command is best run from the cloud console of your cluster. The respective pipelines of this guide are in the [helm-2 branch](https://github.com/codefresh-contrib/helm-sample-app/tree/helm-2). + + + +## CI/CD pipeline with Helm deployment + +It is possible to deploy directly a Helm chart as it exists on the filesystem. This is not the recommended way to use Helm, because you are bypassing the Helm chart repository, but it is certainly the simplest Helm pipeline possible. + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-deploy-pipeline.png" +url="/images/examples/helm/helm-deploy-pipeline.png" +alt="Pipeline for Helm deployment" +caption="Pipeline for Helm deployment" +max-width="100%" +%} + +Here is the whole pipeline: + + `codefresh-do-not-store.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + clone: + title: Cloning main repository... + stage: prepare + type: git-clone + arguments: + repo: codefresh-contrib/helm-sample-app + revision: master + git: github + build: + title: Building Docker Image + stage: build + type: build + working_directory: ./helm-sample-app + arguments: + image_name: helm-sample-app-go + tag: multi-stage + dockerfile: Dockerfile + deploy: + title: Deploying Helm Chart + type: helm + stage: deploy + working_directory: ./helm-sample-app + arguments: + action: install + chart_name: charts/helm-example + release_name: my-go-chart-prod + helm_version: 3.0.2 + kube_context: my-demo-k8s-cluster + custom_values: + - 'buildID=${{CF_BUILD_ID}}' + - 'image_pullPolicy=Always' + - 'image_tag=multi-stage' + - 'replicaCount=3' + - 'image_pullSecret=codefresh-generated-r.cfcr.io-cfcr-default' +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Builds a docker image using a [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +1. Deploys the Helm chart to a cluster named `my-demo-k8s-cluster` using the Helm step [from the Step Marketplace](https://codefresh.io/steps/step/helm). + +Note that in this example `charts/helm-example` refers to the [filesystem location in the code](https://github.com/codefresh-contrib/helm-sample-app/tree/master/charts/helm-example) that was just checked out. + +The deployment will be visible in the [Helm releases dashboard]({{site.baseurl}}/docs/new-helm/helm-releases-management/). + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-release.png" +url="/images/examples/helm/helm-release.png" +alt="Helm release view" +caption="Helm release view" +max-width="100%" +%} + +If you want to run this example yourself, make sure to edit the chart and put your own values there for the Docker image. + +## CI/CD pipeline with Helm deployment that also stores the chart + +It is recommended to use a Helm repository to store your chart before deploying it. This way you know what is deployed in your clusters +and you can also reuse charts in other installations. + +First of all you need to import in your pipeline from the [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) the settings for the internal Helm repository (or any other external repository that you have setup in Codefresh). + This will make available the internal Helm repository to your pipeline so that it can push/pull Helm charts from it. + + {% include image.html + lightbox="true" + file="/images/examples/helm/import-helm-configuration.png" + url="/images/examples/helm/import-helm-configuration.png" + alt="Using the default Helm repository in a Pipeline" + caption="Using the default Helm repository in a Pipeline" + max-width="40%" + %} + +Once that is done you can change your pipeline to also store the chart first and *then* deploy it. + + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-push-and-deploy-pipeline.png" +url="/images/examples/helm/helm-push-and-deploy-pipeline.png" +alt="Pipeline for Helm deployment that stores chart" +caption="Pipeline for Helm deployment that stores chart" +max-width="100%" +%} + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - store + - deploy +steps: + clone: + title: Cloning main repository... + stage: prepare + type: git-clone + arguments: + repo: codefresh-contrib/helm-sample-app + revision: master + git: github + build: + title: Building Docker Image + stage: build + type: build + working_directory: ./helm-sample-app + arguments: + image_name: helm-sample-app-go + tag: multi-stage + dockerfile: Dockerfile + store: + title: Storing Helm Chart + type: helm + stage: store + working_directory: ./helm-sample-app + arguments: + action: push + chart_name: charts/helm-example + kube_context: my-demo-k8s-cluster + deploy: + type: helm + stage: deploy + working_directory: ./helm-sample-app + arguments: + action: install + chart_name: charts/helm-example + release_name: my-go-chart-prod + helm_version: 3.0.2 + kube_context: my-demo-k8s-cluster + custom_values: + - 'buildID=${{CF_BUILD_ID}}' + - 'image_pullPolicy=Always' + - 'image_tag=multi-stage' + - 'replicaCount=3' + - 'image_pullSecret=codefresh-generated-r.cfcr.io-cfcr-default' +{% endraw %} +{% endhighlight %} + + +After you finish running your pipeline, not only the deployment will take place, but you will also see your chart in your [Helm Chart dashboard]({{site.baseurl}}/docs/new-helm/add-helm-repository/): + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-chart.png" +url="/images/examples/helm/helm-chart.png" +alt="Stored Helm chart" +caption="Stored Helm chart" +max-width="80%" +%} + +It is also possible to [run your own Helm commands]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/#example-custom-helm-commands) in a Codefresh pipeline. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) +* [Using Helm in Codefresh pipelines]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) diff --git a/_docs/example-catalog/import-data-to-mongodb.md b/_docs/example-catalog/import-data-to-mongodb.md new file mode 100644 index 00000000..96c826ae --- /dev/null +++ b/_docs/example-catalog/import-data-to-mongodb.md @@ -0,0 +1,57 @@ +--- + +title: "Import data to MongoDB" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/import-data-to-mongodb-in-composition/ + - /docs/on-demand-test-environment/example-compositions/import-data-to-mongodb/ +toc: true +--- + +If you want to import/restore or to do something else before using mongo db in your application, you can look at the following example. + +You just need to create Dockerfile for mongo seed service and provide the command to prepare mongo db. In this case it's command `mongoimport` + + `Dockerfile mongo_seed` +{% highlight docker %} +FROM mongo +COPY init.json /init.json +CMD mongoimport --host mongodb --db exampleDb --collection contacts --type json --file /init.json --jsonArray +{% endhighlight %} + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Let's quickly review the contents of this file: + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + mongodb: + image: mongo + command: mongod --smallfiles + ports: + - 27017 + + mongo_seed: + image: ${{mongo_seed}} + links: + - mongodb + + client: + image: ${{build_prj}} + links: + - mongodb + ports: + - 9000 + environment: + - MONGO_URI=mongodb:27017/exampleDb +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +You can add the following example to your GitHub or Bitbucket account, and build the [example](https://github.com/codefreshdemo/cf-example-manage-mongodb){:target="_blank"}. +{{site.data.callout.end}} diff --git a/_docs/example-catalog/integration-tests-with-mongo.md b/_docs/example-catalog/integration-tests-with-mongo.md new file mode 100644 index 00000000..e11fd4eb --- /dev/null +++ b/_docs/example-catalog/integration-tests-with-mongo.md @@ -0,0 +1,101 @@ +--- +title: "Integration Tests with Mongo" +description: "Launching a MongoDB service container" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/nodejsmongo/ + - /docs/testing/unit-tests/unit-tests-with-mongo/ +toc: true +--- + +In this example we will see a NodeJS project that is using MongoDB for data storage. For the integration test phase we will launch an instance of MongoDB in order to run a set of [Mocha tests](https://mochajs.org/). + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/mongodb-integration-tests.png" +url="/images/examples/integration-tests/mongodb-integration-tests.png" +alt="MongoDB integration tests with Codefresh" +caption="MongoDB integration tests with Codefresh" +max-width="90%" +%} + +The Mocha tests are looking for a MongoDB connection at `mongo:27017`. + +## The example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/example_nodejs_mongo](https://github.com/codefreshdemo/example_nodejs_mongo). The repository contains the NodeJS source code and the Mocha tests. + +You can play with it locally by using Docker compose to launch both the application and the MongoDB datastore. + +## Create a pipeline with MongoDB integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_nodejs_mongo" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "node-mongo-app" + tag: "master" + dockerfile: "Dockerfile" + stage: build + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_app_image}}' + environment: + - MONGO_PORT=27017 + commands: + # MongoDB is certainly up at this point + - cd /src + - npm test + services: + composition: + mongo: + image: mongo:latest + ports: + - 27017 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_app_image}}' + commands: + - "nslookup mongo" + - "nc -z mongo 27017" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. [Builds a Docker image]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) with the application source code as well as the Mocha tests +1. Runs mocha tests while launching a [service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for an active MongoDB instance + +Notice that we also use the `readiness` property in the testing phase so that we can verify MongoDB is ready and listening, before running the tests. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +- [Integration Tests with Postgres]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) +- [Integration Tests with MySQL]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mysql/) +- [Integration Tests with Redis]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-redis/) + + + diff --git a/_docs/example-catalog/integration-tests-with-mysql.md b/_docs/example-catalog/integration-tests-with-mysql.md new file mode 100644 index 00000000..e08ee064 --- /dev/null +++ b/_docs/example-catalog/integration-tests-with-mysql.md @@ -0,0 +1,113 @@ +--- +title: "Integration Tests with MySQL" +description: "Launching a MySQL service container" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/nodejsmysql/ + - /docs/testing/unit-tests/unit-tests-with-mysql/ + - /docs/setup-unit-tests/ + - /docs/testing/unit-tests/unit-tests-with-composition/ + - /docs/run-unit-tests-with-composition/ + - /docs/unit-tests-with-database/ + - /docs/testing/unit-tests/unit-tests-with-database/ + - /docs/yaml-examples/examples/integration-tests-with-database/ +toc: true +--- + +In this example we will see a NodeJS project that is using MySQL for data storage. For the integration test phase we will launch an instance of MySQL in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/mysql-integration-tests.png" +url="/images/examples/integration-tests/mysql-integration-tests.png" +alt="MySQL integration tests with Codefresh" +caption="MySQL integration tests with Codefresh" +max-width="90%" +%} + +The Integration tests are looking for a MySQL connection at `test_mysql_db:3306`. + +## The example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-unit-tests-with-composition](https://github.com/codefreshdemo/cf-example-unit-tests-with-composition). The repository contains the NodeJS source code and the simple integration test. + +You can play with it locally by using Docker compose to launch both the application and the MySQL Database. + +## Create a pipeline with MySQL integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/cf-example-unit-tests-with-composition" + revision: "master" + git: github + stage: prepare + build_test_image: + title: "Building Test Docker Image" + type: "build" + image_name: "mysql-tests" + tag: "master" + dockerfile: "Dockerfile" + stage: build + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + environment: &test_mysql_vars + - MYSQL_ROOT_PASSWORD=admin + - MYSQL_USER=my_user + - MYSQL_PASSWORD=admin + - MYSQL_DATABASE=nodejs + - MYSQL_HOST=test_mysql_db + commands: + # MySQL is certainly up at this point + - cd /usr/src/app + - npm test + services: + composition: + test_mysql_db: + image: mysql:5.7 + ports: + - 3306 + environment: *test_mysql_vars # Same MYSQL_HOST, MYSQL_USER etc. + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_test_image}}' + commands: + - "nslookup test_mysql_db" + - "nc -z test_mysql_db 3306" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). +1. [Builds a Docker image]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) with the integration test. +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for an active MySQL instance passing the required environment variables (that match what the test is expecting). + +Notice that both the DB as well as the tests share a set of variables (`MYSQL_PASSWORD`, `MYSQL_USER` etc.) and thus we use [YAML anchors]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#using-yaml-anchors-to-avoid-repetition) to avoid duplication. + +Notice that we also use the `readiness` property in the testing phase so that we can verify MySQL is ready and listening, before running the tests. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +- [Integration Tests with Postgres]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) +- [Integration Tests with Redis]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-redis/) +- [Integration Tests with Mongo]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mongo/) + + diff --git a/_docs/example-catalog/integration-tests-with-postgres.md b/_docs/example-catalog/integration-tests-with-postgres.md new file mode 100644 index 00000000..43e419f8 --- /dev/null +++ b/_docs/example-catalog/integration-tests-with-postgres.md @@ -0,0 +1,99 @@ +--- +title: "Integration Tests with Postgres" +description: "Launching a PostgreSQL service container" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/unit-tests-with-postgres/ + - /docs/testing/unit-tests/unit-tests-with-postgres/ +toc: true +--- + +In this example we will see a NodeJS project that is using PostgreSQL for data storage. For the integration test phase we will launch an instance of PostgreSQL in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/postgresql-integration-tests.png" +url="/images/examples/integration-tests/postgresql-integration-tests.png" +alt="PostgreSQL integration tests with Codefresh" +caption="PostgreSQL integration tests with Codefresh" +max-width="90%" +%} + +The Integration tests are looking for a PostgreSQL connection at `postgres:5432`. + +## The example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/example_nodejs_postgres](https://github.com/codefreshdemo/example_nodejs_postgres). The repository contains the NodeJS source code and the simple integration test. + +You can play with it locally by using Docker compose to launch both the application and the PostgreSQL Database. + +## Create a pipeline with PostgreSQL integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_nodejs_postgres" + revision: "master" + git: github + stage: prepare + run_integration_tests: + title: "Running integration tests" + stage: test + image: node:6.9.1 + environment: &test_postgresql_vars + - POSTGRES_USER=user + - POSTGRES_PASSWORD=admin + - POSTGRES_DB=todo + commands: + # PostgreSQL is certainly up at this point + - npm install -g gulp + - npm install + - npm test + services: + composition: + postgres: + image: postgres:11.5 + ports: + - 5432 + environment: *test_postgresql_vars # Same POSTGRES_USER, POSTGRES_PASSWORD etc. + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: postgres:11.5 + commands: + - "pg_isready -h postgres" + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for an active PostgreSQL instance passing the required environment variables (that match what the test is expecting). + +Notice that both the DB as well as the tests share a set of variables (`POSTGRES_USER`, `POSTGRES_PASSWORD` etc.) and thus we use [YAML anchors]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/#using-yaml-anchors-to-avoid-repetition) to avoid duplication. + +Notice that we also use the `readiness` property in the testing phase so that we can verify PostgreSQL is ready and listening, before running the tests. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +- [Integration Tests with MySQL]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mysql/) +- [Integration Tests with Redis]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-redis/) +- [Integration Tests with Mongo]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mongo/) +- [Preload a DB with tests data]({{site.baseurl}}/docs/yaml-examples/examples/populate-a-database-with-existing-data/) + + diff --git a/_docs/example-catalog/integration-tests-with-redis.md b/_docs/example-catalog/integration-tests-with-redis.md new file mode 100644 index 00000000..45d21884 --- /dev/null +++ b/_docs/example-catalog/integration-tests-with-redis.md @@ -0,0 +1,129 @@ +--- +title: "Integration Tests with Redis" +description: "Launching a Redis service container" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/python-redis/ + - /docs/testing/unit-tests/unit-tests-with-redis/ +toc: true +--- + +In this example we will see a Python project that is using Redis for storing a web counter. For the integration test phase we will launch both the application and an instance of Redis in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/redis-integration-tests.png" +url="/images/examples/integration-tests/redis-integration-tests.png" +alt="Redis integration tests with Codefresh" +caption="Redis integration tests with Codefresh" +max-width="90%" +%} + +The application will be launched with a hostname `web` while Redis will be at `redis:6379`. + +## The example Python project + +You can see the example project at [https://github.com/codefreshdemo/example_python_redis](https://github.com/codefreshdemo/example_python_redis). The repository contains the Python source code and a test script. + +You can play with it locally by using Docker compose to launch both the application and the Redis datastore. + +## Create a pipeline with Redis integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_python_redis" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "python-redis-app" + tag: "latest" + dockerfile: "Dockerfile" + stage: build + build_test_image: + title: "Building Docker Test Image" + type: "build" + image_name: "python-redis-app-tests" + tag: "latest" + dockerfile: "Dockerfile.test" + stage: test + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + commands: + # Redis and app are certainly up at this point + - sh ./test.sh + services: + composition: + redis: + image: redis:latest + ports: + - 6379 + web: + image: '${{build_app_image}}' + ports: + - 80 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_test_image}}' + commands: + - "nslookup redis" + - "nslookup web" + - "nc -z redis 6379" + - "nc -z web 80" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. [Builds a Docker image]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) with the application itself +1. Builds a helper image that contains `nc` and `curl` that will be used for the integration tests +1. Runs the test script while launching two [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) (one for the app and one for Redis) + +Notice that we also use the `readiness` property in the testing phase so that we can verify that both the application +as well as Redis are up, before running the tests. + +## The integration test script + +The integration test is very simple. It just uses `curl` to hit the Python endpoint and `grep` to check for a well known string. + + `test.sh` +{% highlight sh %} +#!bin/bash + +if curl web | grep -q 'Visits: '; then + echo "Tests passed!" + exit 0 +else + echo "Tests failed!" + exit 1 +fi +{% endhighlight %} + +Notice that we use the helper image both for running the test (because of `curl`) and for testing the readiness (because of `nc`). In a more complex application these could be two completely different images. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +- [Integration Tests with Postgres]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) +- [Integration Tests with MySQL]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mysql/) +- [Integration Tests with Mongo]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mongo/) diff --git a/_docs/example-catalog/java/gradle.md b/_docs/example-catalog/java/gradle.md new file mode 100644 index 00000000..76697af5 --- /dev/null +++ b/_docs/example-catalog/java/gradle.md @@ -0,0 +1,208 @@ +--- +title: "Java Example with Gradle and Docker" +description: "Create Docker images for Spring/Gradle" +excerpt: "" +group: learn-by-example +sub_group: java +redirect_from: + - /docs/java/gradle/ +toc: true +--- + +Codefresh can work with Gradle builds in a similar manner as with [Maven builds]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/). + +## The example Gradle project + +You can see the example project at [https://github.com/codefresh-contrib/gradle-sample-app](https://github.com/codefresh-contrib/gradle-sample-app). The repository contains a Spring Boot 2 project built with Gradle with the following tasks: + +* `gradle test` runs unit tests. +* `gradle build` creates a self-contained jar file (using Spring boot). + +Once launched the application presents a simple message at localhost:8080 and also at the various `/actuator/health` endpoints. + +## Gradle and Docker (multi-stage builds) + +The easiest way to use Gradle is with [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/). With multi-stage builds a Docker build can use one base image for compilation/packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of Gradle, you can use a base image that has the full JDK and Gradle itself, while the final image has the JRE and nothing else. + +The example project is actually using multi-stage builds by default. + +Here is the multi-stage Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM gradle:4.7.0-jdk8-alpine AS build +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +RUN gradle build --no-daemon + +FROM openjdk:8-jre-slim + +EXPOSE 8080 + +RUN mkdir /app + +COPY --from=build /home/gradle/src/build/libs/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Gradle image +1. Copies the Java source code inside the container +1. Compiles the code and runs unit tests (with `Gradle build`) +1. Discards the Gradle image with all the compiled classes/unit test results etc. +1. Starts again from the JRE image and copies **only** the JAR file created before + +We start Gradle without the long-running daemon, as the deamon is best used during local development only and not in CI/CD pipelines. + +### Create a CI pipeline for Gradle (multi-stage Docker builds) + +Because in multi-stage builds Docker itself handles most of the build process, moving the project to Codefresh is straightforward. We just need [a single step](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml) that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/gradle-sample-app' + revision: master + git: github + BuildingDockerImage: + title: Building Docker Image + stage: build + type: build + image_name: gradle-sample-app + working_directory: ./ + tag: 'multi-stage' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This will compile/test/package the Gradle application and create a Docker image. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/gradle-multistage.png" +url="/images/learn-by-example/java/gradle-multistage.png" +alt="Gradle Multi-stage Docker build" +caption="Gradle Multi-stage Docker build" +max-width="80%" +%} + +Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## Packaging an existing Jar in a Docker image + +It also possible to have a simpler Dockerfile that only packages the final jar which was already created in the CI/CD pipeline (i.e. outside of Docker). + +A [simpler Dockerfile](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/Dockerfile.only-package) is also provided at the same repository. It uses the base JRE image and just copies the JAR file inside the container. + + `Dockerfile.only-package` +{% highlight docker %} +{% raw %} +FROM openjdk:8-jre-slim + +EXPOSE 8080 + +RUN mkdir /app + +COPY build/libs/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] +{% endraw %} +{% endhighlight %} + +This means that _before_ building the Docker image, the compilation step (`gradle build`) is expected to be finished already. Therefore, in the `codefresh.yml` file we need at least two steps. The first one should prepare the JAR file and the second +one should create the Docker image. + +### Create a CI pipeline for a Gradle JAR + +The repository also contains a premade [Codefresh YAML file](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh-package-only.yml) that creates a JAR file first and then packages it in a Docker image. + +Here are the full contents of the file. + + `codefresh-package-only.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - package + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/gradle-sample-app' + revision: master + git: github + MyUnitTests: + title: Compile/Unit test + stage: test + image: gradle:4.7.0-jdk8-alpine + commands: + - gradle test --no-daemon --build-cache --gradle-user-home=/codefresh/volume/.gradle -Dmaven.repo.local=/codefresh/volume/m2 + BuildMyJar: + title: Packaging Jar file + stage: package + image: gradle:4.7.0-jdk8-alpine + commands: + - gradle build --no-daemon --build-cache --gradle-user-home=/codefresh/volume/.gradle -Dmaven.repo.local=/codefresh/volume/m2 + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: gradle-sample-app + working_directory: ./ + tag: 'non-multi-stage' + dockerfile: Dockerfile.only-package +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). The next two steps are [freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/), while the last one is a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/gradle-ci-pipeline.png" +url="/images/learn-by-example/java/gradle-ci-pipeline.png" +alt="Gradle pipeline" +caption="Gradle pipeline" +max-width="80%" +%} + +After checking out the code we use the standard [Gradle Docker image](https://hub.docker.com/_/gradle/) to run unit tests. We also pass parameters that disable the Gradle daemon, enable the build cache and also change the cache folder to reside in the Codefresh volume. + +### Using the Gradle cache in Codefresh + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#how-caching-works-in-codefresh) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Gradle cache we make sure that Codefresh will cache automatically the Gradle libraries resulting in much faster builds. We also place in the shared volume the local maven repo so that all jars that are created by Gradle (i.e. with an `install` task) are also available to the next pipeline stage. + +The next step is similar to the previous one, but this time we actually build the JAR file. We define again a custom cache folder so when you run the build you will see that Gradle will automatically pick the cache from the previous step. All Codefresh steps in a pipeline [run on the same workspace]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps), so the build results from one step are visible to the next. + +The last step is a Docker build. We name our image **gradle-sample-app** and tag it with a string `non-multi-stage` but of course you can use any other tag name that you wish. +Once the pipeline is finished you will see the Spring Boot 2 Docker image your [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +## What to read next + +* [Spring Maven example]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/java/publish-jar.md b/_docs/example-catalog/java/publish-jar.md new file mode 100644 index 00000000..c5f8929a --- /dev/null +++ b/_docs/example-catalog/java/publish-jar.md @@ -0,0 +1,117 @@ +--- +title: "Publish Jar" +description: "How to upload a JAR file to Nexus or artifactory" +excerpt: "" +group: learn-by-example +sub_group: java +toc: true +--- + +Even though Codefresh has great support for containers, it can still be used for traditional JAR uploads of libraries or applications that are not dockerized yet. In this example we will compile a JAR and upload it to Nexus. The process is the same for Artifactory or any other package manager. + +For a Java application with Docker, see the [Gradle]({{site.baseurl}}/docs/learn-by-example/java/gradle/) or + [Maven example]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/). + +## The example Java library project + +You can see the example project at [https://github.com/codefresh-contrib/plain-jar-sample-lib](https://github.com/codefresh-contrib/plain-jar-sample-lib). The repository contains a simple Java library built with Maven with the following goals: + +* `mvn package` creates a jar file of the library. It also runs unit tests. +* `mvn upload` uploads the jar to a package manager such as Nexus or Artifactory. + +We use Nexus for this example. To upload the Jar manually first edit the `pom.xml` with the URL of the package manager. The project also includes a [settings.xml](https://github.com/codefresh-contrib/plain-jar-sample-lib/blob/master/settings.xml) with parameterized credential. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-browser.png" +url="/images/learn-by-example/java/nexus-browser.png" +alt="The Nexus package manager" +caption="The Nexus package manager" +max-width="80%" +%} + +From your workstation you can upload the jar manually with: + + +``` +mvn -s settings.xml -Dserver.password=my-nexus-user -Dserver.username=my-nexus-pass deploy +``` +If you then visit Nexus you should see your JAR file in the snapshots repository. + +## Create a CI pipeline for publishing a JAR file + +[Create a new pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) in Codefresh and define as parameters your Nexus credentials. You could also use [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) or any other credential mechanism you already use in your other pipelines. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-credentials.png" +url="/images/learn-by-example/java/nexus-credentials.png" +alt="Parameters for Nexus" +caption="Parameters for Nexus" +max-width="50%" +%} + +Then copy/paste the [Codefresh YAML file](https://github.com/codefresh-contrib/plain-jar-sample-lib/blob/master/codefresh.yml) in the pipeline editor. +Here are the full contents of the file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/plain-jar-sample-lib' + revision: master + git: github + publish_jar: + title: Upload to nexus + image: 'maven:3.5.2-jdk-8-alpine' + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -s settings.xml -Dserver.password=${{NEXUS_PASS}} -Dserver.username=${{NEXUS_USER}} deploy +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). The next step is a [freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) one and packages the jar file. We also use the [Codefresh volume for caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/#traditional-build-caching). + +You can define the version of Maven/JDK you want to use by picking the appropriate image from Dockerhub, or using any of your own images (even from [external registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/)). + +Note the use of the two user-defined environment variables passed to `server.password` and `server.username`. You will need to define those yourself. See the documentation on [User Procided Variables]({{site.baseurl}}/docs/codefresh-yaml/variables/#user-provided-variables). +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/publish-jar-pipeline.png" +url="/images/learn-by-example/java/publish-jar-pipeline.png" +alt="Publish JAR pipeline" +caption="Publish JAR pipeline" +max-width="100%" +%} + +Once the pipeline has finished you should see the JAR file in the Nexus browser UI. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-upload.png" +url="/images/learn-by-example/java/nexus-upload.png" +alt="Upload finished" +caption="Upload finished" +max-width="70%" +%} + +You can use the same pipeline for Artifactory or any other compliant Java package registry. + + + + + +## What to read next + +* [Gradle example]({{site.baseurl}}/docs/learn-by-example/java/gradle/) +* [Spring boot example]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + + + diff --git a/_docs/example-catalog/java/spring-boot-2.md b/_docs/example-catalog/java/spring-boot-2.md new file mode 100644 index 00000000..5078714c --- /dev/null +++ b/_docs/example-catalog/java/spring-boot-2.md @@ -0,0 +1,256 @@ +--- +title: "Spring Boot 2/Maven" +description: "Create Docker images for Spring/Maven" +excerpt: "" +group: learn-by-example +sub_group: java +redirect_from: + - /docs/spring-boot-2/ + - /docs/java/spring-boot-2/ +toc: true +--- + +Spring Boot is quickly becoming a very popular choice for building Java back-end applications, and is a bit different compared to traditional application servers, since it includes a servlet container in the final JAR file allowing +for self-contained Java Archives (JAR files). + +Codefresh can easily handle Spring Boot applications that are dockerized either in the traditional way or using multi-stage builds. + +## The example Java project + +You can see the example project at [https://github.com/codefresh-contrib/spring-boot-2-sample-app](https://github.com/codefresh-contrib/spring-boot-2-sample-app). The repository contains a Spring Boot 2 project built with Maven with the following goals: + +* `mvn package` creates a jar file that can be run on its own (exposes port 8080). It also runs unit tests. +* `mvn verify` runs integration tests as well. The application is launched locally as part of the Maven lifecycle. + +Once launched the application presents a simple message at localhost:8080 and also at the various `/actuator/health` endpoints. You can use the standard `spring-boot:run` command to run it locally (without Docker). + +## Spring Boot 2 and Docker (package only) + +A Dockerfile is also provided at the same repository. It uses the base JRE image and just copies the JAR file inside the container. + + `Dockerfile.only-package` +{% highlight docker %} +{% raw %} +FROM java:8-jre-alpine + +EXPOSE 8080 + +RUN mkdir /app +COPY target/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] + +HEALTHCHECK --interval=1m --timeout=3s CMD wget -q -T 3 -s http://localhost:8080/actuator/health/ || exit 1 + +{% endraw %} +{% endhighlight %} + +This means that _before_ building the Docker image, the compilation step (`mvn package`) is expected to be finished already. Therefore, in the `codefresh.yml` file we need at least two steps. The first one should prepare the JAR file and the second +one should create the Docker image. + +### Create a CI pipeline for Spring + +The repository also contains a premade [Codefresh YAML file]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) that you can use as a starting point in your own Spring Boot 2 projects. + +Here are the full contents of the file. + + `codefresh-package-only.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build + - 'integration 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 + run_unit_tests: + title: Compile/Unit test + stage: test + image: 'maven:3.5.2-jdk-8-alpine' + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository package + build_app_image: + title: Building Docker Image + type: build + stage: build + image_name: spring-boot-2-sample-app + working_directory: ./ + tag: 'non-multi-stage' + dockerfile: Dockerfile.only-package + run_integration_tests: + title: Integration test + stage: 'integration test' + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository verify -Dserver.host=http://my-spring-app + services: + composition: + my-spring-app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://my-spring-app:8080/" +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). The next step is a [freestyle]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) one and packages the jar file. Next we have a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) that creates the docker image. Finally we have another freestyle +step that uses [service containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) to run integration tests. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/spring-boot-steps.png" +url="/images/learn-by-example/java/spring-boot-steps.png" +alt="Spring boot pipeline" +caption="Spring boot pipeline" +max-width="80%" +%} + +After checking out the code we use the standard [Maven Docker image](https://hub.docker.com/_/maven/) to compile the Spring Boot source code and create a JAR file. We also pass a parameter that changes the Maven cache location folder. The reason for this parameter is that the default Maven location is `/root/.m2` which is defined as a volume (and thus discarded after each build). + +### Caching the Maven dependencies + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Maven repo on the project folder (the `m2_repository` name is arbitrary) we make sure that Codefresh will cache automatically the Maven libraries resulting in much faster builds. + +The next step is a Docker build. We name our image **spring-boot-2-sample-app** and tag it with a string `non-multi-stage` but of course you can use any other tag name that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/spring-boot-docker-image.png" +url="/images/learn-by-example/java/spring-boot-docker-image.png" +alt="Spring Boot Docker image" +caption="Spring Boot Docker image" +max-width="80%" +%} + +Once the pipeline is finished you will see the Spring Boot 2 Docker image your [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +The last step is similar to the unit tests, but this time we run integration tests. We define again a custom cache folder so when you run the build you will see that Maven will automatically pick the cache from the previous step. All Codefresh steps in a pipeline [run on the same workspace]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps), so the build results from one step are visible to the next. + +>Notice that because the [Maven lifecycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) also executes the previous steps in a build, the `mvn verify` command essentially will run `mvn package` as well. In theory we could just have the _Integration_ step in this pipeline on its own. That step would build the code, run unit and integration tests all in one stage. For demonstration purposes however, we include two steps so that you can see the correct usage of Maven cache. + + +## Spring Boot 2 and Docker (multi-stage builds) + +Docker added [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/) at version 17.05. With multi-stage builds a Docker build can use one base image for compilation/packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of Java, multistage builds allow for the compilation itself to happen during the build process, even though the final Docker image will not contain a full JDK. + + +Here is the multi-stage build definition: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM maven:3.5.2-jdk-8-alpine AS MAVEN_TOOL_CHAIN +COPY pom.xml /tmp/ +RUN mvn -B dependency:go-offline -f /tmp/pom.xml -s /usr/share/maven/ref/settings-docker.xml +COPY src /tmp/src/ +WORKDIR /tmp/ +RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package + +FROM java:8-jre-alpine + +EXPOSE 8080 + +RUN mkdir /app +COPY --from=MAVEN_TOOL_CHAIN /tmp/target/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] + +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the standard Maven Docker image +1. Copies only the `pom.xml` file inside the container +1. Runs a mvn command to download all dependencies found in the `pom.xml` +1. Copies the rest of the source code in the container +1. Compiles the code and runs unit tests (with `mvn package`) +1. Discards the Maven image with all the compiled classes/unit test results etc +1. Starts again from the JRE image and copies **only** the JAR file created before + +The order of the steps is tuned so that it takes advantage of the layer caching built-in to Docker. +If you change something in the source code Docker already has a layer with Maven dependencies so they +will not be re-downloaded again. Only if you change the `pom.xml` file itself, Docker will start again from the lowest layer. + +Again, we define a custom location for the Maven cache (using the `settings-docker.xml` file). This way the Maven dependencies are placed inside the container and they will be cached automatically with the respective layer (Read more about this technique [at the official documentation](https://github.com/carlossg/docker-maven#packaging-a-local-repository-with-the-image)). + +### Create a CI pipeline for Spring (multi-stage Docker builds) + +Because in multi-stage builds Docker itself handles most of the build process, moving the project to Codefresh is straightforward. We just need [a single step](https://github.com/codefresh-contrib/spring-boot-2-sample-app/blob/master/codefresh.yml) that creates the Docker image after checking out the code. The integration test step is the same as before. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build + - 'integration 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 + build_app_image: + title: Building Docker Image + type: build + stage: build + image_name: spring-boot-2-sample-app + working_directory: ./ + tag: 'multi-stage' + dockerfile: Dockerfile + run_integration_tests: + title: Integration test + stage: 'integration test' + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository verify -Dserver.host=http://my-spring-app + services: + composition: + my-spring-app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://my-spring-app:8080/" +{% endraw %} +{% endhighlight %} + +This will compile/test/package the Spring Boot application and create a Docker image. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## What to read next + +* [Gradle example]({{site.baseurl}}/docs/learn-by-example/java/gradle/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + + + diff --git a/_docs/example-catalog/launch-composition.md b/_docs/example-catalog/launch-composition.md new file mode 100644 index 00000000..83a616f5 --- /dev/null +++ b/_docs/example-catalog/launch-composition.md @@ -0,0 +1,87 @@ +--- +title: "Launch Composition" +description: "Create a dynamic environment to preview your feature" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/launch-composition-1/ +toc: true +--- +Using this repository, we will help you get up to speed with basic functionality such as: building Docker images and launching compositions. +This project uses `Node JS` to build an application which will eventually become a distributable Docker image. + +## Looking around + +In the root of this repository you'll find a file named `codefresh.yml`, this is our [pipeline definition]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +stages: + - prepare + - package + - launch +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: codefreshdemo/cf-example-launch-composition + revision: 'master' + git: github + stage: prepare + build_image: + title: Building Image + type: build + #Important: rename this image to to a valid repository in your registry. For example: myUserName/vote + image_name: example-launch-compose + #Dockerfile location should be relative to the working directory + dockerfile: Dockerfile + tag: master + stage: package + launch_composition: + title: Launch Composition + type: launch-composition + composition: + version: '2' + services: + app: + image: example-launch-compose:master + ports: + - 3000 + environment_name: 'cf-example-launch-composition' + entry_point: app + fail_fast: false + stage: launch +{% endhighlight %} + +The pipeline clones the source code, builds a docker image and then + [creates a preview environment]({{site.baseurl}}/docs/codefresh-yaml/steps/launch-composition/) with that image. + + +{{site.data.callout.callout_warning}} +##### Your environments are limited +Be aware that the number of environments you can run is limited. When using the same environment name the old one would terminate before launching the new environment. That way you can control the number of environments running in your account. +{{site.data.callout.end}} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [**repository**](https://github.com/codefreshdemo/cf-example-launch-composition) in GitHub and follow the instructions there. +{{site.data.callout.end}} + +Here is the end result: + +{% include image.html +lightbox="true" +file="/images/examples/composition/launch-composition-example.png" +url="/images/examples/composition/launch-composition-example.png" +alt="Launch composition example" +caption="Launch composition example" +max-width="90%" +%} + +## What to read next + +* [Unit tests]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +* [Integration tests]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-database/) +* [Preview environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) \ No newline at end of file diff --git a/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md b/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md new file mode 100644 index 00000000..af5f36f9 --- /dev/null +++ b/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md @@ -0,0 +1,57 @@ +--- +title: "Launching a composition and defining a service environment variable using a file" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/launching-a-composition-and-passing-a-service-environment-variable-using-a-file/ +toc: true +old_url: /docs/launching-a-composition-and-passing-a-service-environment-variable-using-a-file +--- +Sometimes when launching a composition there is a need to pass many environment variables to a specific service. +In order to do that you can use docker-compose 'env_file' field on any service and use files from the current working directory from which the composition is being launched. +This will work for both 'composition' and 'launch-composition' step types. + +{{site.data.callout.callout_info}} +##### Using env_file will not work in case you are launching a composition directly from the Compositions view because it is being launched in an empty working directory. + +Consider moving the composition launch as part of a usual pipeline which will give you ability to use files from your cloned repository. +{{site.data.callout.end}} + +## Examples +Compositions are being launch inside a working directory, which is the cloned repository by default. +This means that you can always reference an 'env_file' exactly like you would reference a docker-compose file. + + `Inline Composition` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + + inline_composition: + title: Launch inline composition + type: launch-composition + environment_name: 'environment name' + composition: + version: '3' + services: + service: + image: alpine + env_file: ./env-file +{% endraw %} +{% endhighlight %} + + + `Composition from file` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + + composition_from_file: + title: Launch composition from file + type: launch-composition + composition: './docker-compose.yml' + environment_name: 'environment name' +{% endraw %} +{% endhighlight %} diff --git a/_docs/example-catalog/mobile.md b/_docs/example-catalog/mobile.md new file mode 100644 index 00000000..70f7a777 --- /dev/null +++ b/_docs/example-catalog/mobile.md @@ -0,0 +1,9 @@ +--- +title: "Mobile Apps" +description: "How to build Mobile applications with Codefresh CI/CD pipelines" +group: learn-by-example +toc: true +--- +This section contains Codefresh examples for Mobile application. + +- [Android]({{site.baseurl}}/docs/learn-by-example/mobile/android/) diff --git a/_docs/example-catalog/nodejs-angular2-mongodb.md b/_docs/example-catalog/nodejs-angular2-mongodb.md new file mode 100644 index 00000000..aa5b679a --- /dev/null +++ b/_docs/example-catalog/nodejs-angular2-mongodb.md @@ -0,0 +1,50 @@ +--- +title: "NodeJS + Angular2 + MongoDB" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/nodejs-angular2-mongodb/ + - /docs/on-demand-test-environment/example-compositions/nodejs-angular2-mongodb/ +toc: true +--- +This tutorial will walk you through the process of adding the following: + +- Build client +- Build server +- Launch composition + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Let's quickly review the contents of this file: + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + mongodb: + image: mongo + ports: + - 28017 + server: + image: ${{build_server}} + environment: + - MONGO_URI=mongodb://mongodb/exampleDb + links: + - mongodb + ports: + - 9000 + client: + image: ${{build_client}} + ports: + - 3000 +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/nodejs-angular2-mongo){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + diff --git a/_docs/example-catalog/nodejs/lets-chat.md b/_docs/example-catalog/nodejs/lets-chat.md new file mode 100644 index 00000000..649f5cf3 --- /dev/null +++ b/_docs/example-catalog/nodejs/lets-chat.md @@ -0,0 +1,119 @@ +--- +title: "Let's Chat example" +description: "Create Docker images for Node/Express.js applications" +group: learn-by-example +sub_group: nodejs +redirect_from: + - /docs/lets-chat/ +toc: true +--- + +Let’s Chat is self-hosted chat app for small to big teams. + +## The example Node.JS project + +You can see the example project at [https://github.com/codefreshdemo/demochat](https://github.com/codefreshdemo/demochat). The repository contains the source code of the project along with two Dockerfiles (one for unit tests) and various docker-compose configurations + +The project requires a Mongo Database to work and by default it uses port 5000 for its web interface. + +## Create a CI pipeline for Node.js + +Creating a CI/CD pipeline for NodeJS is very easy, because Codefresh has built-in steps for creating Docker images and running commands with containers. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/nodejs-pipeline.png" +url="/images/learn-by-example/nodejs/nodejs-pipeline.png" +alt="Building and testing a Node.js application" +caption="Building and testing a Node.js application" +max-width="100%" +%} + +Here is the [full pipeline](https://github.com/codefreshdemo/demochat/blob/master/codefresh.yml) that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "unit" + - "build" + - "integration" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefreshdemo/demochat" + revision: "master" + stage: "clone" + + build_dev_image: + title: "Building Dev image" + type: "build" + image_name: "codefreshdemo/demochat" + working_directory: "${{clone}}" + tag: "dev" + dockerfile: "Dockerfile.dev" + stage: "unit" + + test: + title: "Running test" + type: "freestyle" + image: ${{build_dev_image}} + working_directory: /root/demochat + commands: + - 'npm run test' + stage: "unit" + + build_image: + title: "Building App image" + type: "build" + image_name: "codefreshdemo/demochat" + working_directory: "${{clone}}" + tag: "dev" + dockerfile: "Dockerfile" + stage: "build" + + integration_step: + type: composition + stage: 'integration' + composition: + version: '2' + services: + app: + image: ${{build_image}} + links: + - mongo + ports: + - 5000 + mongo: + image: mongo + composition-candidates: + main: + image: nhoag/curl + command: bash -c "sleep 30 && curl http://app:5000/" | echo 'works' + +{% endraw %} +{% endhighlight %} + +> Note that you should change `codefreshdemo` in the clone step with your own Github account if you fork the repository. Also in both build steps you should change `codefreshdemo/demochat` with your own image name that is compliant to your Dockerhub account or other connected registry. + +This pipeline has 4 [stages]({{site.baseurl}}/docs/codefresh-yaml/stages/) and performs the following: + + 1. clones the source code using the [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step + 1. Builds a Docker image for unit tests with the [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) + 1. Runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) in the Docker image that was just created with a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + 1. Building a Docker image for the final application + 1. Runs [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) using a [composition step]({{site.baseurl}}/docs/codefresh-yaml/steps/composition/) + +If you run the pipeline multiple times, you will also see the [Codefresh caching mechanisms]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) in action for faster build times. + +## What to read next + +* [Voting app example]({{site.baseurl}}/docs/learn-by-example/nodejs/voting-app/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/nodejs/react.md b/_docs/example-catalog/nodejs/react.md new file mode 100644 index 00000000..e79b7a5b --- /dev/null +++ b/_docs/example-catalog/nodejs/react.md @@ -0,0 +1,174 @@ +--- +title: "React example with Yarn" +description: "Create Docker images for React applications" +group: learn-by-example +sub_group: nodejs +toc: true +--- + +Codefresh can work with React projects as with any [Node.js project]({{site.baseurl}}/docs/learn-by-example/nodejs/). + +## The example React project + +You can see the example project at [https://github.com/codefresh-contrib/react-sample-app](https://github.com/codefresh-contrib/react-sample-app). The repository contains a React starter project with the following tasks: + +* `yarn test` runs unit tests. +* `yarn start` to start the application locally. +* `yarn build` to create a production deployment. + +Once launched the application presents a simple page at localhost:3000. + +## React and Docker (multi-stage builds) + +The easiest way to build a React.JS application is with [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/). With multi-stage builds a Docker build can use one base image for packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of React, you can use a base image that has Node and all testing utilities, while the final image has your server (e.g. nginx) with the static content and nothing else. + +The example project is actually using multi-stage builds by default. + +Here is the multi-stage Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM node:8.16 as build-deps +WORKDIR /usr/src/app +COPY package.json yarn.lock ./ +RUN yarn +COPY . ./ +RUN yarn build + +FROM nginx:1.12-alpine +COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Node/Yarn image +1. Copies the dependencies inside the container +1. Copies the source code and creates all static files +1. Discards the Node.js image with all the JavaScript libraries +1. Starts again from the nginx image and copies **static build result** created before + +The resulting is very small, as it contains only packaged/minified files. + +## Create a CI pipeline for React.js (Docker build) + +Creating a CI/CD pipeline for React is very easy, because Codefresh can run any [node image](https://hub.docker.com/_/node/) that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/react-pipeline-docker.png" +url="/images/learn-by-example/nodejs/react-pipeline-docker.png" +alt="Creating a Docker image for react.js" +caption="Creating a Docker image for react.js" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml) that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/react-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: node:8.16 + commands: + - yarn install + - yarn test + environment: + - CI=true + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: react-sample-app + working_directory: ./ + tag: 'with-nginx' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, runs unit tests and finally creates a Docker image. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## Building a React.Js application without Docker + +If your application is not dockerized yet, you can still create a pipeline that runs any command that you would run locally. You can also choose which Node version is used for each step of the pipeline by defining a different docker image for each step. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/react-pipeline-build.png" +url="/images/learn-by-example/nodejs/react-pipeline-build.png" +alt="Building a Reach.js application" +caption="Building a Reach.js application" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/react-sample-app/blob/master/codefresh-only-build.yml) that creates a production deployment of all files. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/react-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: node:11.0 + commands: + - yarn install + - yarn test + environment: + - CI=true + MyReactBuild: + title: Packaging application + stage: build + image: node:8.16 + commands: + - yarn build +{% endraw %} +{% endhighlight %} + +Notice that for demonstration purposes we uses node 11 for the tests, and node 8 for the packaging. Normally you should use the same version of node/Yarn for all your steps, but Codefresh pipelines are flexible on version of tools. + +Even when you don't create a Docker image, Codefresh still caches your workspace volume. This means that `node_modules` are downloaded only once. All subsequent builds will be much faster. + +## What to read next + +* [Node examples]({{site.baseurl}}/docs/learn-by-example/nodejs/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/nodejs/voting-app.md b/_docs/example-catalog/nodejs/voting-app.md new file mode 100644 index 00000000..48c5da61 --- /dev/null +++ b/_docs/example-catalog/nodejs/voting-app.md @@ -0,0 +1,88 @@ +--- +title: "Voting app" +description: "" +excerpt: "" +group: learn-by-example +sub_group: nodejs +redirect_from: + - /docs/voting-app/ + - /docs/nodejs/voting-app/ +toc: true +--- +This voting application is a demo with which you can build an advanced composition that uses `Python, Redis, Postgres, Node.js, and .Net`. + +The demo shows how to create a complex, micro-services application and push images to your docker registry. + +## Looking around +In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: +#build all the images + build_image_vote: + title: Building Voting Image + type: build + #Important: rename this image to a valid repository in your registry. For example: myUserName/vote + image_name: containers101/vote + #The directory should be relative to git repository that is used for cloning + working_directory: ./vote/ + #Dockerfile location should be relative to the working directory + dockerfile: Dockerfile + + build_image_result: + title: Building Result Image + type: build + image_name: containers101/result + working_directory: ./result/ + dockerfile: Dockerfile + + build_image_worker: + title: Building Worker Image + type: build + image_name: containers101/worker + working_directory: ./worker/ + dockerfile: Dockerfile + + +#Push all the images + push_to_registry_vote: + title: Pushing to Vote Docker Registry + type: push + + #A candidate is the image that we want to push to registry + candidate: '${{build_image_vote}}' + + # You can push the image with whatever tag you want. In our example we use CF_BRANCH, which is a variable in + # the build process, accessible throughout the entire flow. + tag: '${{CF_BRANCH}}' + + push_to_registry_result: + title: Pushing to Result Docker Registry + type: push + candidate: '${{build_image_result}}' + tag: '${{CF_BRANCH}}' + + push_to_registry_worker: + title: Pushing to Worker Docker Registry + type: push + candidate: '${{build_image_worker}}' + tag: '${{CF_BRANCH}}' +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/containers101/voting-app){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## What to read next + +* [React example]({{site.baseurl}}/docs/learn-by-example/nodejs/react/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/nomad.md b/_docs/example-catalog/nomad.md new file mode 100644 index 00000000..fbe6821a --- /dev/null +++ b/_docs/example-catalog/nomad.md @@ -0,0 +1,226 @@ +--- +title: "Deploy to Nomad" +description: "Deploy Docker images to a Nomad cluster with Codefresh" +group: yaml-examples +sub_group: examples +toc: true +--- + +Even though Codefresh has great support for Kubernetes and Helm deployments, there is no lock-in on using just Kubernetes. Codefresh can deploy on any infrastructure. + + +[Nomad](https://www.nomadproject.io/) is an alternative scheduling platform from Hashicorp. It supports docker containers (like Kubernetes) but you can also use Nomad to schedule VMs, Java apps, Go apps or any other standalone executable. + +There are several public Docker Images with Nomad, so it is very easy to use Codefresh pipelines to deploy to a Nomad cluster. + + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-ci-pipeline.png" +url="/images/examples/nomad/nomad-ci-pipeline.png" +alt="Deploying to Nomad with Codefresh" +caption="Deploying to Nomad with Codefresh" +max-width="80%" +%} + +In this example we are going to use the image at [https://hub.docker.com/r/djenriquez/nomad](https://hub.docker.com/r/djenriquez/nomad). + +## The example Nomad project + +You can see the example project at [https://github.com/codefresh-contrib/nomad-sample-app](https://github.com/codefresh-contrib/nomad-sample-app). The repository contains a simple job specification that deploys a docker container on nomad cluster. + + +Here is the whole job file: + + `docker-job.hcl` +{% highlight hcl %} +{% raw %} +job "example-job" { + # Specify this job should run in the region named "us". Regions + # are defined by the Nomad servers' configuration. + #region = "us" + + # Spread the tasks in this job between us-west-1 and us-east-1. + datacenters = ["dc1"] + + # Run this job as a "service" type. Each job type has different + # properties. See the documentation below for more examples. + type = "service" + + # Specify this job to have rolling updates, two-at-a-time, with + # 30 second intervals. + update { + stagger = "30s" + max_parallel = 1 + } + + # A group defines a series of tasks that should be co-located + # on the same client (host). All tasks within a group will be + # placed on the same host. + group "example-group" { + # Specify the number of these tasks we want. + count = 3 + + # Create an individual task (unit of work). This particular + # task utilizes a Docker container to front a web application. + task "example-task" { + # Specify the driver to be "docker". Nomad supports + # multiple drivers. + driver = "docker" + + # Configuration is specific to each driver. + config { + image = "r.cfcr.io/$CF_ACCOUNT/$CF_REPO_NAME:$CF_BRANCH_TAG_NORMALIZED" + + auth { + username = "$CF_ACCOUNT" + password = "$CFCR_LOGIN_TOKEN" + server_address = "r.cfcr.io" + } + + port_map { + http = 8080 + } + } + + # The service block tells Nomad how to register this service + # with Consul for service discovery and monitoring. + service { + # This tells Consul to monitor the service on the port + # labelled "http". Since Nomad allocates high dynamic port + # numbers, we use labels to refer to them. + port = "http" + + check { + type = "http" + path = "/" + interval = "10s" + timeout = "2s" + } + } + + # Specify the maximum resources required to run the task, + # include CPU, memory, and bandwidth. + resources { + cpu = 500 # MHz + memory = 128 # MB + + network { + mbits = 100 + + + port "http" {} + + + + } + } + } + } +} + +{% endraw %} +{% endhighlight %} + +Notice that the job specification has several [Codefresh variables]({{site.baseurl}}/docs/codefresh-yaml/variables/) embedded. We will use [envsubst](https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html) in our pipeline to replace +them with the correct values. + +## Prerequisites + +You need to create a Codefresh account and have a Nomad cluster running. You need to decide on how Codefresh will communicate +with the nomad cluster. In this simple example we just use the `NOMAD_ADDR` variable to point the nomad client to our cluster. In a production environment you should use proper [ACL](https://www.nomadproject.io/guides/security/acl.html) and [certificate](https://www.nomadproject.io/guides/security/securing-nomad.html) variables as well. + + +In this example the Nomad cluster is already setup on a VM at Google cloud. + +You also need to create a [token for the Docker registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) so that Nomad can pull your private images on the cluster. + +## Create a CI/CD pipeline for Nomad deployments + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "deploy" +steps: + main_clone: + type: "git-clone" + title: "Clone main repository..." + repo: "codefresh-contrib/nomad-sample-app" + revision: "${{CF_BRANCH}}" + stage: "clone" + build: + title: "Building Docker Image" + type: "build" + image_name: "nomad-sample-app" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + prepareJob: + title: "Preparing Nomad job" + image: bhgedigital/envsubst + stage: deploy + commands: + - envsubst < docker-job.hcl > docker-job-export.hcl + - cat docker-job-export.hcl + runJob: + title: "Deploying Nomad job" + image: djenriquez/nomad + stage: deploy + commands: + - nomad run docker-job-export.hcl +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Uses a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) to create a Docker image for a simple Go application. The image is automatically pushed to the default Docker registry +1. Runs `envsubst` to replace all variables in the job spec. These include: + * the Registry token so that Nomad can access the default Docker registry + * The docker image name and tag to be deployed +1. Runs the job with another [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) (i.e. Deploys the image to Nomad) + + +Run the pipeline and see your deployment succeed. + +Here are the environment variables defined for this pipeline. + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-variables.png" +url="/images/examples/nomad/nomad-variables.png" +alt="Pipeline variables for Nomad deployments" +caption="Pipeline variables for Nomad deployments" +max-width="50%" +%} + + +The `NOMAD_ADDR` variable is holding the URL of the cluster. The `CFCR_LOGIN_TOKEN` variable holds authentication for the Codefresh Docker registry. + +## Verify the deployment + +Nomad also comes with its own UI that can show you the result of a deployment. + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-ui-deployment.png" +url="/images/examples/nomad/nomad-ui-deployment.png" +alt="Nomad UI deployment" +caption="Nomad UI deployment" +max-width="80%" +%} + +You can also use [Terraform]({{site.baseurl}}/docs/yaml-examples/examples/terraform/) in Codefresh pipelines. + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/non-git-checkout.md b/_docs/example-catalog/non-git-checkout.md new file mode 100644 index 00000000..dec584ef --- /dev/null +++ b/_docs/example-catalog/non-git-checkout.md @@ -0,0 +1,101 @@ +--- +title: "Checking out from other Source Control systems" +description: "Work with non-git repositories" +group: yaml-examples +sub_group: examples +toc: true +--- + +Codefresh has [Native Git support]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) but you can still use any other version control system such as SVN, CVS, hg, etc. + +The only requirement is that you find or create a Docker image that contains the client for that source control system and then use a +[freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) to run it. + +## Checking out Subversion code + +There is already a public [Docker image with the svn client](https://hub.docker.com/r/jgsqware/svn-client/), so it is very easy to run it in a Codefresh pipeline. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomCheckout: + title: Performing SVN checkout + image: jgsqware/svn-client + commands: + - pwd + - rm -rf audacity-svn + - svn checkout https://svn.code.sf.net/p/audacity/svn/ audacity-svn + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l /codefresh/volume/' +{% endraw %} +{% endhighlight %} + +Notice the `rm` command before the clone step. This makes sure that every time the pipeline will run the `svn checkout` step will happen in an empty directory. + + + +## Checking out Mercurial or CVS Code + +It is very simple to use any other Source control system in a Codefresh pipeline. The easiest way is to just call the respective executable. Here are two examples: + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myHgStep: + title: Using HG + image: alpine:latest + commands: + - apk add --no-cache mercurial + - hg --version + - hg clone https://www.mercurial-scm.org/repo/hg mercurial-repo + myCvsStep: + title: Using CVS + image: alpine:latest + commands: + - apk add --no-cache cvs + - cvs --version + - cvs -d :pserver:anonymous@cvs.project-open.net:/home/cvsroot checkout -c +{% endraw %} +{% endhighlight %} + +A much faster way is to create your own Dockerfile that includes the client you need and then mention that image directly in the freestyle step. + + +## Checking out Perforce code + +Codefresh has created a [Perforce plugin](https://hub.docker.com/r/codefresh/cf-p4-plugin/tags) which packs the p4 client into a Docker image in order to be used from Codefresh pipelines: + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomCheckout: + title: Performing Perforce checkout + image: codefresh/cf-p4-plugin:latest + commands: + - mkdir -p /codefresh/volume/p4repo/ + - p4 client -o | grep -v '#' | sed '/Root:/c\Root:/codefresh/volume/p4repo/' | p4 client -i + - cd /codefresh/volume/p4repo/ && p4 rec + - 'ls -la' + environment: + - P4PORT=serveradress:serverport + - P4CLIENT=clientname + - P4USER=username + - P4PASSWD=password +{% endraw %} +{% endhighlight %} + +The environments variables should be defined in [Codefresh shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/). + + +## What to read next + +* [Native Git checkout]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout/) +* [Running custom git commands]({{site.baseurl}}/docs/yaml-examples/examples/git-checkout-custom/) +* [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +* [Git Clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) diff --git a/_docs/example-catalog/packer-gcloud.md b/_docs/example-catalog/packer-gcloud.md new file mode 100644 index 00000000..5e543064 --- /dev/null +++ b/_docs/example-catalog/packer-gcloud.md @@ -0,0 +1,134 @@ +--- +title: "Deploy to a Virtual Machine" +description: "Deploy to Google Cloud in a Codefresh pipeline with Packer" +group: yaml-examples +sub_group: examples +toc: true +--- + +Even though Codefresh is Kubernetes-native and designed for containers, it can still deploy traditional applications in the form of Virtual Machines to any Cloud provider. + +In this example we will use +[Packer](http://www.packer.io/) to package an application into a VM disk image that will then be launched in Google Cloud. +Because Packer itself is already offered [in a Docker container](https://hub.docker.com/r/hashicorp/packer/), it is very easy to run Packer in a Codefresh pipeline. + +Google also offers a [Docker image for GCloud](https://hub.docker.com/r/google/cloud-sdk/) making the launching of the VM straightforward in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/packer-codefresh-pipeline.png" +url="/images/examples/packer-gcloud/packer-codefresh-pipeline.png" +alt="Running Packer inside Codefresh" +caption="Running Packer inside Codefresh" +max-width="80%" +%} + +This Codefresh pipeline creates a VM image and then uses it to launch a Google Compute instance. + + +## The example Packer/Gcloud project + +You can see the example project at [https://github.com/codefresh-contrib/vm-packer-sample-app](https://github.com/codefresh-contrib/vm-packer-sample-app). The repository contains a simple Go application as well as a packer template. + +You can play with it locally after installing the `packer` and `gcloud` executables. + +## Prerequisites + +You need to create a Codefresh account and a Google account first. Then you need to create a [Service account Key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) which will allow `packer` and `gcloud` to communicate with Google cloud. + + +Add your service account json as a pipeline variable called `SERVICE_ACCOUNT`. The content of this variable will be used +in order to authenticate to Google cloud. + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/service-account-variable.png" +url="/images/examples/packer-gcloud/service-account-variable.png" +alt="Using a Service Account JSON in Codefresh" +caption="Using a Service Account JSON in Codefresh" +max-width="50%" +%} + +## Create a CI/CD pipeline for Packer/GCloud + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: 'codefresh-contrib/vm-packer-sample-app' + git: github + revision: 'master' + stage: prepare + SetupAuth: + title: 'Setup GCloud Auth' + image: 'alpine' + stage: prepare + commands: + - echo $SERVICE_ACCOUNT > account.json + BuildMyApp: + title: Compiling App code + stage: build + image: 'golang:1.12' + commands: + - go build -o sample src/sample/trivial-web-server.go + CreatePackerImage: + title: Baking VM image + stage: build + image: 'hashicorp/packer' + commands: + - packer validate my-google-cloud-example.json + - packer build -force my-google-cloud-example.json + DeployToVM: + title: Deploying to VM + stage: deploy + image: 'google/cloud-sdk' + commands: + - gcloud auth activate-service-account --key-file=account.json + - gcloud config set project firstkubernetes-176201 + - gcloud compute instances create packer-demo-codefresh --image codefresh-simple-ubuntu-vm --zone europe-west1-b --metadata-from-file startup-script=startup.sh --tags http-server --preemptible --quiet + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Saves the content of the variable that holds the Google account as a file called `account.json` +1. Compiles the Go application with a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +1. Runs `packer` to create a VM image based on Ubuntu that also contains the simple Go application +1. Runs `gcloud` to launch a VM with the image that was just created + + +Run the pipeline and see your deployment succeed. You can customize the image by editing the [Packer template](https://github.com/codefresh-contrib/vm-packer-sample-app/blob/master/my-google-cloud-example.json). + +Once the VM has finished launching you can access it with your web browser. + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/web-app-url.png" +url="/images/examples/packer-gcloud/web-app-url.png" +alt="Accessing the VM application" +caption="Accessing the VM application" +max-width="70%" +%} + + +You can follow the same procedure for any other cloud that has an API/CLI (such as AWS, Azure, Digital Ocean etc). + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/php.md b/_docs/example-catalog/php.md new file mode 100644 index 00000000..219b7224 --- /dev/null +++ b/_docs/example-catalog/php.md @@ -0,0 +1,132 @@ +--- +title: "Create a Docker image for Php" +description: "Using Codefresh pipelines" +group: learn-by-example +toc: true +--- + +Codefresh can work with Php projects using any of the popular frameworks (Laravel, Symphony, CakePHp etc.) + +## The example php project + +You can see the example project at [https://github.com/codefresh-contrib/php-composer-sample-app](https://github.com/codefresh-contrib/php-composer-sample-app). The repository contains a simple Php project that uses [composer](https://getcomposer.org/) as a package manager. + +The dockerfile uses [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/) to minimize the size of the docker image. + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM composer:1.9.3 as vendor + +WORKDIR /tmp/ + +COPY composer.json composer.json +COPY composer.lock composer.lock + +RUN composer install \ + --ignore-platform-reqs \ + --no-interaction \ + --no-plugins \ + --no-scripts \ + --prefer-dist + + +FROM php:7.2-apache-stretch + +COPY . /var/www/html +COPY --from=vendor /tmp/vendor/ /var/www/html/vendor/ +{% endraw %} +{% endhighlight %} + + +## Create a Docker image for Php project + +An [example pipeline](https://github.com/codefresh-contrib/php-composer-sample-app/blob/master/codefresh.yml) is also offered in the git repository. +It contains just two [steps]({{site.baseurl}}/docs/codefresh-yaml/steps/). A [clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) to fetch the code and a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) to create a Docker image. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/php-composer-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-php-image + working_directory: ./ + tag: master + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Once you run this pipeline Codefresh will create a Docker image for the Php application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/php-cicd-pipeline.png" +url="/images/learn-by-example/php/php-cicd-pipeline.png" +alt="Creating a docker image for php" +caption="Creating a docker image for php" +max-width="80%" +%} + +Notice that all dependencies are downloaded when the dockerfile is created. + + + + +## Launch Docker images + +Codefresh can also launch Docker images (using Docker swarm behind the scenes). With each Codefresh account you get access to a limited number of Docker environments that can host any Docker image or Docker compose file. + +First find your images in the [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/launch-docker-image.png" +url="/images/learn-by-example/php/launch-docker-image.png" +alt="Launching a Docker image" +caption="Launching a Docker image" +max-width="80%" +%} + +Click on the launch button and a new pipeline will run for deployment: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/test-environment-url.png" +url="/images/learn-by-example/php/test-environment-url.png" +alt="Getting the environment url" +caption="Getting the environment url" +max-width="80%" +%} + +Notice that the pipeline logs show the dynamic URL of the application. Simply visit it with your browser +and you will see the result. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/test-environment.png" +url="/images/learn-by-example/php/test-environment.png" +alt="Application preview" +caption="Application preview" +max-width="80%" +%} + +Notice that these environments are only for testing and previewing your application as it is developed. They are **NOT** for production purposes. + + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/populate-a-database-with-existing-data.md b/_docs/example-catalog/populate-a-database-with-existing-data.md new file mode 100644 index 00000000..ae477c0a --- /dev/null +++ b/_docs/example-catalog/populate-a-database-with-existing-data.md @@ -0,0 +1,153 @@ +--- +title: "Populate a database with existing data" +description: "Preloading test data before integration tests" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/populate-a-database-with-existing-data-copied/ +toc: true +old_url: /docs/populate-a-database-with-existing-data-copied +was_hidden: true +--- +In an another example we have seen how you can run [integration tests with a database]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) such as PostgreSQL. Sometimes however, the integration tests require the database to already have some test data beforehand. With Codefresh you can use the [setup block]({{site.baseurl}}/docs/codefresh-yaml/service-containers/#preloading-data-to-databases) in service containers to preload data to a db. + + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/preload-data-to-db.png" +url="/images/examples/integration-tests/preload-data-to-db.png" +alt="Preloading test data to a DB" +caption="Preloading test data to a DB" +max-width="90%" +%} + +In this pipeline the database is populated with data from an SQL file. + +## The example PostgreSQL project + +You can see the example project at [https://github.com/codefresh-contrib/preload-db-integration-tests](https://github.com/codefresh-contrib/preload-db-integration-tests). The repository contains a simple integration test and an SQL file that inserts test data. + +The SQL file creates a single table in the db: + + `preload.sql` +{% highlight sql %} +{% raw %} +CREATE TABLE link ( + ID serial PRIMARY KEY, + url VARCHAR (255) NOT NULL, + name VARCHAR (255) NOT NULL, + description VARCHAR (255), + rel VARCHAR (50) +); + +INSERT INTO link (url, name) +VALUES + ('http://www.google.com','Google'), + ('http://www.azure.microsoft.com','Azure'), + ('http://www.codefresh.io','Codefresh'); +{% endraw %} +{% endhighlight %} + + +To work with the project locally, you need to have `docker`, `golang` and `postgres-client` installed on your workstation first. + +``` +$ docker run -p 5432:5432 postgres:11.5 +``` + +Then open another terminal and load the test data: + +``` +$ psql -h localhost -U postgres < testdata/preload.sql +``` + +A Postgres instance is now running at `localhost:5432` and you can run the tests with: + +``` +$ go test -v +``` + + +## Create a pipeline the preloads test data to PostgreSQL + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: +- prepare +- package +- test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefresh-contrib/preload-db-integration-tests" + revision: "master" + title: "Checking out source code" + git: github + stage: prepare + package_my_app: + stage: package + image: 'golang:1.13' + title: "Compile code" + commands: + - 'go build' + run_my_db_tests: + stage: test + image: 'golang:1.13' + title: "Running integration tests" + commands: + - 'go test -v' + environment: + - POSTGRES_HOST=my_postgresql_db + services: + composition: + my_postgresql_db: + image: postgres:11.5 + ports: + - 5432 + readiness: + timeoutSeconds: 30 + initialDelaySeconds: 10 + periodSeconds: 15 + image: 'postgres:11.5' + commands: + - "pg_isready -h my_postgresql_db -U postgres" + setup: + image: 'postgres:11.5' + commands: + - "psql -h my_postgresql_db -U postgres < /codefresh/volume/preload-db-integration-tests/testdata/preload.sql" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). +1. Compiles the code with a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that runs `go build` +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) for an active PostgreSQL instance. Before tests are run we launch another container with the `psql` executable to load db data + + +> In this simple example we use `psql` to preload the database. In a production application you might also use dedicated db tools such as [liquibase](https://hub.docker.com/r/liquibase/liquibase) or [flyway](https://hub.docker.com/r/flyway/flyway) or other command line tools that communicate with your database. + +Notice that we also use the `readiness` property in the testing phase so that we can verify PostgreSQL is ready and listening, before running the tests. The exact order of events is: + +1. Codefresh launches `postgres:11.5` at port 5432. +1. It then launches another container in the same network with `pg_isready` in order to wait for the DB to be up. +1. Then it launches a third container with `psql` to preload data. +1. Finally it launches a container with `golang:1.13` to run the actual tests. + +All containers are discarded after the pipeline has finished. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration Tests with Postgres]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) +- [Integration Tests with MySQL]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mysql/) +- [Integration Tests with Redis]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-redis/) +- [Integration Tests with Mongo]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mongo/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) + + diff --git a/_docs/example-catalog/pulumi.md b/_docs/example-catalog/pulumi.md new file mode 100644 index 00000000..ef90bb89 --- /dev/null +++ b/_docs/example-catalog/pulumi.md @@ -0,0 +1,117 @@ +--- +title: "Deploy with Pulumi" +description: "Use Pulumi in a Codefresh pipeline with Docker" +group: yaml-examples +sub_group: examples +toc: true +--- + +[Pulumi](https://pulumi.io/) is a platform for *Infrastructure as Code*. It works like Terraform but allows you to use a proper programming language (TypeScript, Python, Go) in order to describe your infrastructure (instead of a configuration language). + +You can use Pulumi to deploy to Kubernetes or any other supported cloud platform. Because Pulumi itself is already offered [in a Docker container](https://hub.docker.com/r/pulumi/pulumi), it is very easy to run Pulumi in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/pulumi/pulumi-pipeline.png" +url="/images/examples/pulumi/pulumi-pipeline.png" +alt="Running Pulumi inside Codefresh" +caption="Running Pulumi inside Codefresh" +max-width="80%" +%} + +## The example Pulumi project + +You can see the example project at [https://github.com/codefresh-contrib/pulumi-sample-app](https://github.com/codefresh-contrib/pulumi-sample-app). The repository contains a simple Pulumi stack based on Kubernetes and TypeScript. + +You can play with it locally after installing the `pulumi` executable. + +## Prerequisites + +You need to create a Codefresh account and a Pulumi account first. Then you need to create a [Pulumi token](https://app.pulumi.com/account/tokens) which will allows Codefresh to communicate with Pulumi. + +[Add a Kubernetes cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/) in your Codefresh account from any cloud provider. + +Codefresh automatically creates a kubeconfig in any [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) with all your clusters. This is the same way that Pulumi communicated with Kubernetes, so the integration between Codefresh and Pulumi is ready out of the box. + +Create a [stack](https://pulumi.io/reference/stack.html) in Pulumi or use the one provided in the example. + +Finally add you Pulumi token as a pipeline variable called `PULUMI_ACCESS_TOKEN`. All freestyle steps have automatic access to all pipeline variables, and Pulumi will search for a token by default with this name when logging in. + + +## Create a CI/CD pipeline for Pulumi + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + stage: prepare + git: github-1 + BuildProject: + title: Build project + stage: build + image: pulumi/pulumi + commands: + - yarn install + SelectMyCluster: + title: Select K8s cluster + stage: deploy + image: codefresh/kubectl:1.13.3 + commands: + - kubectl config get-contexts + - kubectl config use-context "kostis-demo@FirstKubernetes" + RunPulumi: + title: Deploying + stage: deploy + image: pulumi/pulumi + commands: + - pulumi stack select dev --non-interactive + - pulumi stack --non-interactive + - pulumi up --non-interactive +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Runs `yarn install` to download dependencies. In this example we use TypeScript, but Go and Python would work as well (or any other language supported by Pulumi) +1. Chooses the cluster that will be used for deployments (if you have more than one). Use your own cluster name as seen in the [Kubernetes dashboard]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/) of Codefresh +1. Runs `pulumi up` with the same target cluster + +The pipeline needs a [single environment variable]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) that holds the content of your Pulumi Token. + + +{% include image.html +lightbox="true" +file="/images/examples/pulumi/pulumi-access-token.png" +url="/images/examples/pulumi/pulumi-access-token.png" +alt="Passing the Pulumi Token in the pipeline parameters" +caption="Passing the Pulumi Token in the pipeline parameters" +max-width="60%" +%} + +Run the pipeline and see your deployment succeed. + +## Handling Pull requests + +You can easily use the same pipeline or a different one for pull requests. In this case replace the `pulumi up` command with `pulumi preview`. Even better you can add an [approval step]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) to allows humans to inspect the pipeline first. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/python/django.md b/_docs/example-catalog/python/django.md new file mode 100644 index 00000000..92ba1375 --- /dev/null +++ b/_docs/example-catalog/python/django.md @@ -0,0 +1,175 @@ +--- +title: "Python Django example" +description: "Create Docker images for Python applications" +excerpt: "" +group: learn-by-example +sub_group: python +redirect_from: + - /docs/django/ + - /docs/python/django/ +toc: true +--- +Codefresh can work with Python projects using any of the popular frameworks. In this page we will see Django. For a Flask example see the [quick start guide]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/). + +## The example Django project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-python-django](https://github.com/codefreshdemo/cf-example-python-django). The repository contains a Django starter project with the following commands: + +* `pip install -r requirements.txt` install dependencies. +* `python -m unittest composeexample.utils` runs unit tests. +* `python manage.py runserver 0.0.0.0:8000` to start the application locally. + + +Once launched the application presents the Django starter page at localhost:8000. + +## Django and Docker + +The easiest way to build a Django application is with a Dockerfile that contains everything. This is very convenient as the Docker image can contain everything you need (i.e. app plus test frameworks) inside a pipeline. + + +Here is the Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM python:3.6-slim + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 +RUN mkdir /code +WORKDIR /code +RUN pip install --upgrade pip +COPY requirements.txt /code/ + +RUN pip install -r requirements.txt +COPY . /code/ + +EXPOSE 8000 + +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Python image +1. Sets some environment variables +1. Copies the dependencies file inside the container +1. Upgrades pip and installs all dependencies +1. Copies the rest of the source code +1. Starts the Django app + +You can build this image locally on your workstation and then launch it to test the application. + +### Create a CI pipeline for Python/Django + +Creating a CI/CD pipeline for Django is very easy if you already have the Dockerfile with all required dependencies. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/python/python-build-test.png" +url="/images/learn-by-example/python/python-build-test.png" +alt="Creating a Docker image for Python" +caption="Creating a Docker image for Python" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml) that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - test +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/cf-example-python-django' + revision: master + git: github + build_my_image: + title: Building Docker Image + stage: build + type: build + image_name: my-django-image + working_directory: ./ + tag: master + dockerfile: Dockerfile + test_my_image: + title: Running unit tests + stage: test + image: '${{build_my_image}}' + commands: + - python -m unittest composeexample.utils +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, creates a Docker image and then uses the same image to run unit tests. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +### Running tests before building the docker image + +Sometimes if you have a complex application you might want to run integration tests (or other Python commands), *before* building the Docker image. This scenario is also supported natively by Codefresh. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/python/python-test-build.png" +url="/images/learn-by-example/python/python-test-build.png" +alt="Building the image after tests have run" +caption="Building the image after tests have run" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefreshdemo/cf-example-python-django/blob/master/codefresh-build-after-test.yml) builds the docker image after tests have already executed. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/cf-example-python-django' + revision: master + git: github + test_the_code: + title: Run unit tests + stage: test + image: python:3.6-slim + commands: + - pip install -r requirements.txt --cache-dir=/codefresh/volume/pip-cache + - python -m unittest composeexample.utils + build_my_image: + title: Building Docker Image + stage: build + type: build + image_name: my-django-image + working_directory: ./ + tag: full + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for pip which keeps its cache externally (e.g. `~/.cache/pip`). By changing the location of the Pip cache on the project folder (the `pip-cache` name is arbitrary) we make sure that Codefresh will cache automatically the Pip libraries resulting in much faster builds. + +## What to read next + +* [Python examples]({{site.baseurl}}/docs/learn-by-example/python/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/python/voting-app.md b/_docs/example-catalog/python/voting-app.md new file mode 100644 index 00000000..bce847bc --- /dev/null +++ b/_docs/example-catalog/python/voting-app.md @@ -0,0 +1,90 @@ +--- +title: "Voting app" +description: "" +excerpt: "" +group: learn-by-example +sub_group: python +redirect_from: + - /docs/voting-app-1/ + - /docs/python/voting-app/ +toc: true +--- +This voting application is a demo with which you can build an advanced composition that uses `Python, Redis, Postgres, Node.js, and .Net`. + +## Looking around +In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + unit-tests: + image: codefresh/buildpacks:nodejs-5 + working-directory : ${{initial-clone}} + commands: + - echo Installing npm modules silent + - npm install + - gulp test + - echo $(date) + + build-step: + #title: Build My Image #Display name for the step + type: build + image-name: containers101/cf-example-result + tag: ${{CF_BRANCH}} + build_arguments: + - OPTION_A=${{OPTION_A}} + - OPTION_B=${{OPTION_B}} + + push-to-registry: + type: push + #candidate: the image from the build step + candidate: ${{build-step}} + tag: ${{CF_BRANCH}} + + integration-tests-step: + type: composition + #location of the compostion on the filesystem of the cloned image + composition: './cf-compositions/voting-app-full.yml' + #run integration only when pushing to master + when: + branch: + only: + - master #can also be regex + composition-candidates: + #this will be the image that we will test + integ-test: + image: containers101/cf-example-tests:master + command: ./tests.sh + composition-variables: + - VOTING_OPTION_A=${{OPTION_A}} + - VOTING_OPTION_B=${{OPTION_B}} + + launch-composition: + type: launch-composition + environment-name: 'Test composition after build' + composition: './cf-compositions/voting-app-full.yml' + composition-variables: + - VOTING_OPTION_A=${{OPTION_A}} + - VOTING_OPTION_B=${{OPTION_B}} + + deploy to ecs: + image: codefresh/cf-deploy-ecs + commands: + - cfecs-update --image-name containers101/cf-example-result --image-tag ${{CF_BRANCH}} eu-west-1 vote-app result + environment: + - AWS_ACCESS_KEY_ID=${{AWS_ACCESS_KEY_ID}} + - AWS_SECRET_ACCESS_KEY=${{AWS_SECRET_ACCESS_KEY}} + when: + condition: + all: + pushCommit: 'includes(lower("${{CF_COMMIT_MESSAGE}}"), "[deploy]") == true' +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/containers101/cf-example-result){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} diff --git a/_docs/example-catalog/ruby.md b/_docs/example-catalog/ruby.md new file mode 100644 index 00000000..cfc42bc7 --- /dev/null +++ b/_docs/example-catalog/ruby.md @@ -0,0 +1,182 @@ +--- +title: "Ruby" +description: "How to build a Ruby On Rails project in Codefresh" +group: learn-by-example +toc: true +--- +Ruby on Rails is a very popular development framework that combines ease of use and a great amount of programming languages. In Codefresh, ROR projects behave like any other web application. You can easily build them, run [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) and launch them on [demo environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/). + +The example application is located at [https://github.com/codefresh-contrib/ruby-on-rails-sample-app](https://github.com/codefresh-contrib/ruby-on-rails-sample-app). + + + +## Dockerize your Ruby on Rails project + +The first step should be to write a [Dockerfile](https://github.com/codefresh-contrib/ruby-on-rails-sample-app/blob/master/Dockerfile) for your Rails project. As an example we will use the following: + + + +`Dockerfile` +{% highlight docker %} +FROM ruby:2.3.1-slim + +RUN apt-get update && \ + apt-get install -y build-essential libcurl4-openssl-dev libxml2-dev libsqlite3-dev libpq-dev nodejs postgresql-client sqlite3 --no-install-recommends && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +ENV APP_PATH /usr/src/app + +RUN mkdir -p $APP_PATH + +COPY Gemfile $APP_PATH +COPY Gemfile.lock $APP_PATH + +WORKDIR $APP_PATH + +RUN bundle install + +COPY . $APP_PATH + +ENV RAILS_ENV development + +RUN bin/rake db:migrate + +RUN bin/rake assets:precompile + +EXPOSE 3000 + +CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] + +{% endhighlight %} + +Notice the order of commands and especially the fact that we copy the `Gemfile` on its own first, so that we take advantage of the Docker layer caching. + +>Codefresh also supports multi-stage docker builds. You can use one parent docker image for preparing your gem modules and another one for actually deployment the application. + +Once you have a Dockerfile, [creating a pipeline in Codefresh]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) is very easy either from the GUI or with the yaml syntax. + +## Simple pipeline with Docker image and unit tests + +A very simple pipeline is one that has only two steps: + +1. Build the docker image +1. Run the tests inside the docker image that was just build + +Here is the example [codefresh.yml](https://github.com/codefresh-contrib/ruby-on-rails-sample-app/blob/master/codefresh.yml) file. + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/ruby-on-rails-sample-app' + revision: master + git: github + BuildingDockerImage: + title: Building Docker Image + type: build + image_name: ruby-on-rails-sample-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + RunningUnitTests: + title: Running Unit Tests + image: '${{BuildingDockerImage}}' + commands: + - rails db:migrate + - rails test +{% endraw %} +{% endhighlight %} + +The first step is a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) named `BuildingDockerImage`. It reads the Dockerfile and creates a Docker image out of it. The second step is a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) called `RunningUnitTests`. It uses the image mentioned in the first step and executes custom commands inside it. + + +## Inspecting your Docker image + +You can see all your latest [Docker artifacts]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images) by selecting *Images* from the left sidebar. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/images.png" +url="/images/learn-by-example/ruby/images.png" +alt="Codefresh built-in Registry" +caption="Codefresh built-in Registry" +max-width="80%" +%} + +You can click on the image and get extra details. One of the tabs contains a visual explanation of the layers contained in the image. This view can be helpful when you are trying to make your Docker images smaller (which is a recommended practice) + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/layers.png" +url="/images/learn-by-example/ruby/layers.png" +alt="Ruby On Rails image filesystem layers" +caption="Ruby On Rails Image filesystem layers" +max-width="70%" +%} + +In Codefresh you can also use any other [external registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) such as Dockerhub, Azure, Google etc. + + +## Previewing the Ruby on Rails application in a Demo environment + +Codefresh has the unique capability of launching Docker images within its infrastructure for a quick demonstration (e.g. to customers and colleagues). + +In the example Rails repository, the default development "environment" is self-contained (it uses sqlite for a database). This makes it very easy to preview. + +Launch the environment by clicking at the rocket icon in the images view. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/launch.png" +url="/images/learn-by-example/ruby/launch.png" +alt="Launching a demo environment" +caption="Launching a demo environment" +max-width="50%" +%} + +A new build will start. Once it is complete your new environment will be created. You can inspect it by clicking in the *Compositions* menu on the left sidebar and then clicking *Running Compositions*. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/environment.png" +url="/images/learn-by-example/ruby/environment.png" +alt="Inspecting a demo environment" +caption="Inspecting a demo environment" +max-width="70%" +%} + +Click the *Open App* icon on the right and your browser will open a new tab with the environment. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/preview.png" +url="/images/learn-by-example/ruby/preview.png" +alt="Previewing a demo environment" +caption="Previewing a demo environment" +max-width="50%" +%} + + +You can share this link with other people in your team. + +>Demo environments are not intended for production purposes. Use them only for quick feedback. They also shutdown automatically after a period of inactivity. + + + +## 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/) +* [On demand environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) +* [Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) + + diff --git a/_docs/example-catalog/run-integration-tests.md b/_docs/example-catalog/run-integration-tests.md new file mode 100644 index 00000000..0b92e9b0 --- /dev/null +++ b/_docs/example-catalog/run-integration-tests.md @@ -0,0 +1,102 @@ +--- +title: "Integration Tests Example" +description: "Launching separate App and test containers" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/run-integration-tests/ +toc: true +--- +In this example we will see a Java/Tomcat project that is using JUnit for unit tests and Spock for integration tests. For the integration test phase we will launch both the application and the tests in order to run the integration tests against a real web instance (i.e. without mocking). + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/integration-tests.png" +url="/images/examples/integration-tests/integration-tests.png" +alt="Integration tests with Codefresh" +caption="Integration tests with Codefresh" +max-width="90%" +%} + +The integration tests will look at the application instance at `app:8080`. + +## The example Java/Tomcat/Spring project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-integration-tests](https://github.com/codefreshdemo/cf-example-integration-tests). The repository contains the Java source code and some integration tests. + +You can play with it locally by using Docker compose to launch both the application and the tests. + +## Create a pipeline with separate integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/cf-example-integration-tests" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "my-spring-app" + tag: "master" + dockerfile: "Dockerfile" + stage: build + build_test_image: + title: "Building Docker Test Image" + type: "build" + image_name: "my-junit-spock-tests" + tag: "master" + dockerfile: "Dockerfile.testing" + stage: test + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + commands: + # Tomcat is certainly up at this point + - mvn verify -Dserver.host=app + services: + composition: + app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://app:8080/wizard/" + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. [Builds a Docker image]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) with only Tomcat and the application WAR +1. Builds a helper image that contains the source code and Maven so that it can run integration tests. +1. Runs the `mvn verify` command in the helper image while launching a [service container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) with the Tomcat/Java image + +Notice that we also use the `readiness` property in the testing phase so that we can verify that the application +is actually up, before running the tests. + +## What to read next + +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Integration Tests with Postgres]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-postgres/) +- [Integration Tests with MySQL]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mysql/) +- [Integration Tests with Mongo]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-mongo/) +- [Integration Tests with Redis]({{site.baseurl}}/docs/yaml-examples/examples/integration-tests-with-redis/) \ No newline at end of file diff --git a/_docs/example-catalog/run-unit-tests.md b/_docs/example-catalog/run-unit-tests.md new file mode 100644 index 00000000..9c4c7a79 --- /dev/null +++ b/_docs/example-catalog/run-unit-tests.md @@ -0,0 +1,105 @@ +--- +title: "Run Unit Tests" +description: "Running unit tests in Codefresh pipelines" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/run-unit-tests/ +toc: true +--- + +As we have explained in the [Unit tests page]({{site.baseurl}}/docs/testing/unit-tests/) Codefresh supports several ways of running unit tests. The most usual scenarios are using an existing Docker Hub image (common with compiled languages such as Java and Go) or using the application image itself (common with languages such as JavaScript/Python/Ruby/PHP). + +In this example we will see both ways using two different applications in a single pipeline. + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/unit-tests-pipeline.png" +url="/images/examples/unit-tests/unit-tests-pipeline.png" +alt="Unit tests with Codefresh" +caption="Unit tests with Codefresh" +max-width="90%" +%} + +In the first case we will run unit tests *before* creating the application docker image, while in the second case we will run unit tests +*inside* the application Docker image. + +## The example Python/Go project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-unit-test](https://github.com/codefreshdemo/cf-example-unit-test). The repository contains two applications (Python and Go) with their respective unit tests. + +You can play with it locally by using Docker commands to package the applications. + +## Create a pipeline with Unit tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - 'Microservice A' + - 'Microservice B' +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: + title: Running Unit tests directly + stage: 'Microservice A' + image: golang:1.12 + working_directory: './golang-app-A' + commands: + - go test -v + build_after_my_tests: + title: Building Go Docker Image + type: build + stage: 'Microservice A' + image_name: my-go-image + working_directory: './golang-app-A' + tag: 'master' + dockerfile: Dockerfile + build_before_my_tests: + title: Building Python Docker Image + type: build + stage: 'Microservice B' + image_name: my-python-image + working_directory: './python-app-B' + tag: 'master' + dockerfile: Dockerfile + run_my_tests_inside_image: + title: Running Unit tests inside App image + stage: 'Microservice B' + image: ${{build_before_my_tests}} + working_directory: '/app' + commands: + - python setup.py test +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Runs unit test for the GO application using the Dockerhub image `golang:1.12` +1. [Builds the Docker image]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) for the Go application +1. Builds the Docker image for the Python application +1. Runs unit tests for the Python application using as runtime context the application image that was just created. + + +Notice that in the second case the tests run in the context of `build_before_my_tests` which is the name of the step that creates the Docker image for Python. See [context variables]({{site.baseurl}}/docs/codefresh-yaml/variables/#context-related-variables) for more information on this technique. + +We generally recommend the first approach, so that your production Docker image does not contain any unit testing libraries or frameworks, but there is no right or wrong choice regarding the way you run unit tests. + +## What to read next + +- [Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +- [Integration test example]({{site.baseurl}}/docs/yaml-examples/examples/run-integration-tests/) +- [Service Containers]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) +- [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/) + diff --git a/_docs/example-catalog/rust.md b/_docs/example-catalog/rust.md new file mode 100644 index 00000000..08f58445 --- /dev/null +++ b/_docs/example-catalog/rust.md @@ -0,0 +1,83 @@ +--- +title: "Compile and test a Rust application" +description: "Using Codefresh pipelines" +group: learn-by-example +toc: true +--- + +Codefresh can work with any Rust application very easily as both `rustc` and `cargo` are already offered in Dockerhub. + +## The example Rust project + +You can see the example project at [https://github.com/codefresh-contrib/rust-sample-app](https://github.com/codefresh-contrib/rust-sample-app). The repository contains a Rust starter project with a dummy unit test. + +* `cargo build` compiles the code. +* `cargo test` runs unit tests +* `cargo clean` removes artifacts and binaries. + + +## Create a CI pipeline for Rust applications + +Creating a CI/CD pipeline for Rust is very easy, because Codefresh can run any [Rust image](https://hub.docker.com/_/rust) that you wish. Rust docker images already contain the `cargo` package manager. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/rust/rust-pipeline.png" +url="/images/learn-by-example/rust/rust-pipeline.png" +alt="Compiling a Rust application in a pipeline" +caption="Compiling a Rust application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/rust-sample-app/blob/master/codefresh.yml) that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "test" +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefresh-contrib/rust-sample-app" + revision: "master" + stage: "clone" + compile: + title: "Building Code" + type: "freestyle" + image: "rust:1.44-stretch" + working_directory: "${{clone}}" + environment: + - CARGO_HOME=/codefresh/volume/cargo + commands: + - "cargo build" + stage: "build" + test: + title: "Running tests" + type: "freestyle" + image: "rust:1.44-stretch" + working_directory: "${{clone}}" + environment: + - CARGO_HOME=/codefresh/volume/cargo + commands: + - "cargo test" + stage: "test" + +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, compiles the code and runs unit tests. In all cases we use the public Docker image of Rust that also contains `cargo`. + +We also pass the `CARGO_HOME` environment variable to place the Cargo cache on the [shared Codefresh volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps). See the [Caching documentation]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/#traditional-build-caching) for more details. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/scala/scala-hello-world.md b/_docs/example-catalog/scala/scala-hello-world.md new file mode 100644 index 00000000..629da23d --- /dev/null +++ b/_docs/example-catalog/scala/scala-hello-world.md @@ -0,0 +1,185 @@ +--- +title: "Scala: Hello World" +description: "Use Scala and Codefresh to clone, package, and build a Docker image" +excerpt: "" +group: learn-by-example +sub_group: scala +redirect_from: + - /docs/scala-hello-world/ +toc: true +--- + +So, you’ve decided to try Codefresh? Welcome on board! + +We’ll help you get up to speed with basic functionality such as: compiling, building Docker images and launching. + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) + +## The Example Scala Application + +This project uses `Scala` to build an application which will eventually become a distributable Docker image. + +You can find the example application on [GitHub](https://github.com/codefresh-contrib/scala-hello-world-app). + +There are two pipeline examples provided in this tutorial: + +- Multi-stage Docker build +- Single stage Docker Build + +## Example Pipeline #1: Single stage Docker Build + +This example uses a single stage Docker build. The pipeline will have three stages: + +- A stage for cloning +- A stage for packaging +- A stage for building + +{% include image.html +lightbox="true" +file="/images/examples/scala/single-stage-pipeline.png" +url="/images/examples/scala/single-stage-pipeline.png" +alt="Codefresh UI pipeline view" +caption="Codefresh UI pipeline view" +max-width="100%" +%} + +Here is the Dockerfile used for this example: + +`Dockerfile-single-stage` +```shell +FROM openjdk:8-jre-alpine3.9 + +COPY . . + +CMD ["java", "-cp", "target/scala-2.12/*.jar:scala-library-2.12.2.jar", "HelloWorld"] +``` + +And here is the pipeline. You can copy and paste it in the inline YAML editor in the UI: + + `codefresh-single-stage.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - clone + - package + - build + +steps: + clone: + title: Cloning repository... + type: git-clone + stage: clone + arguments: + repo: codefresh-contrib/scala-hello-world-app + revision: master + package: + title: Packaging application... + type: freestyle + stage: package + working_directory: ./scala-hello-world-app + arguments: + image: hseeberger/scala-sbt:11.0.6_1.3.9_2.13.1 + commands: + - sbt -Dsbt.ivy.home=/codefresh/volume/ivy_cache clean compile package + - cp /codefresh/volume/ivy_cache/cache/org.scala-lang/scala-library/jars/scala-library-2.12.2.jar . + build_image: + title: Building Docker image... + type: build + working_directory: ${{clone}} + stage: build + arguments: + image_name: codefresh/scala-sample-app + tag: 1.0.0 + dockerfile: Dockerfile-single-stage +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that uses an SBT image that packages the application (note how `sbt.ivy.home` is set to an arbitrarily named directory that is part of the codefresh volume). This ensures we cache dependencies to [speed up builds]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/#caching-the-maven-dependencies), similar to Maven. +3. The last step, `build_image`, is a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) that builds a Docker image using the Dockerfile provided in the repository. + +## Example Pipeline #2: Multi-stage Docker Build + +This example uses a multi stage Docker build. The pipeline will have only two stages this time, as packaging of the app is handled in the Dockerfile itself: + +- A stage for cloning +- A stage for building + +{% include image.html +lightbox="true" +file="/images/examples/scala/multi-stage-pipeline.png" +url="/images/examples/scala/multi-stage-pipeline.png" +alt="Codefresh UI pipeline view" +caption="Codefresh UI pipeline view" +max-width="100%" +%} + +Here, you will find the multi-stage Dockerfile, copying over only the jars we need: + +`Dockerfile-multi-stage` + +```shell +# first stage + +FROM hseeberger/scala-sbt:11.0.6_1.3.9_2.13.1 AS build + +COPY ./ ./ + +RUN sbt compile clean package + +# second stage + +FROM openjdk:8-jre-alpine3.9 + +COPY --from=build /root/target/scala-2.12/*.jar /scala-hello-world-sample-app.jar +COPY --from=build /root/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.2.jar /scala-library-2.12.2.jar + +CMD ["java", "-cp", "scala-hello-world-sample-app.jar:scala-library-2.12.2.jar", "HelloWorld"] +``` +Here is the pipeline, you can copy and paste it into the inline YAML editor: + +`codefresh-multi-stage.yml` + +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - clone + - build + +steps: + clone: + title: Cloning repository... + type: git-clone + stage: clone + arguments: + repo: codefresh-contrib/scala-hello-world-app + revision: master + build_image: + title: Building Docker image... + type: build + working_directory: ${{clone}} + stage: build + arguments: + image_name: codefresh/scala-hello-world-app + tag: 1.0.0 + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that builds our code into a Docker image using the Dockerfile present in the repository + + +## What to Read Next + +- [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) diff --git a/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md b/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md new file mode 100644 index 00000000..301fbe8d --- /dev/null +++ b/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md @@ -0,0 +1,86 @@ +--- +title: "Secure a Docker Container Using HTTP Basic Auth" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/securing-docker-container-with-http-basic-auth/ + - /docs/on-demand-test-environment/examples-compositions/securing-docker-container-with-http-basic-auth/ + - /docs/on-demand-test-environment/example-compositions/secure-a-docker-container-using-http-basic-auth/ +toc: true +--- +Before making a product publicly available, you might want to restrict access to certain users. These are some options to accomplish this goal: + + - Implement custom authentication within the system + - Configure the server to act as a proxy between the user and the application + - Limit access to specific IP addresses + +This article explains how to secure a container by exposing public ports, using an extra NGINX container to act as a proxy. + +## Expose Web App Public Port + + `webapp` +{% highlight yaml %} +{% raw %} +version: '3' +services: + web: + image: codefreshio/webapp + ports: + - "3000" +{% endraw %} +{% endhighlight %} + +The architecture for this step is displayed in the diagram below. In this step example, Docker is forwarding an internal 3000 port to the host 80 port. + +{% include +image.html +lightbox="true" +file="/images/a65a871-codefresh_webapp_container.png" +url="/images/a65a871-codefresh_webapp_container.png" +alt="codefresh_webapp_container.png" +max-width="40%" +%} + +## Add NGINX Proxy +To secure the web-app we are going to specify these commands in the ```docker-compose.yml``` file. + +1. Remove the port that maps from the web-app (it won't be directly accessible) +2. Add an extra NGINX container with custom configuration (proxy all traffic) +3. Configure NGINX to communicate with the web-app + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + web: + image: ${{build-prj}} + auth: + image: ${{build-nginx}} + ports: + - 80 + links: + - web + environment: + USER: ${{USERNAME}} + PASS: ${{PASSWORD}} +{% endraw %} +{% endhighlight %} + +The architecture for the ```docker-compose.yml``` file is displayed in the diagram below. + +{% include +image.html +lightbox="true" +file="/images/72a8d7a-codefresh_nginx_container.png" +url="/images/72a8d7a-codefresh_nginx_container.png" +alt="codefresh_nginx_container.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-basic-auth-container){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} diff --git a/_docs/example-catalog/sending-the-notification-to-jira.md b/_docs/example-catalog/sending-the-notification-to-jira.md new file mode 100644 index 00000000..f43e7b91 --- /dev/null +++ b/_docs/example-catalog/sending-the-notification-to-jira.md @@ -0,0 +1,88 @@ +--- +title: "Sending the notification to Jira" +description: "" +group: yaml-examples +sub_group: examples +toc: true +--- + +The plugin marketplace offers several freestyle steps that can be used in your Codefresh pipeline through steps. + +One of those steps is the [Jira Issue Manager](https://codefresh.io/steps/step/jira-issue-manager). + +Prerequisites +* [Have a Codefresh Pipeline]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/) set-up +* [Have a Jira Account](https://www.atlassian.com/software/jira) + +This documentation is using the following [example](https://github.com/codefresh-contrib/jira-demo-app). You can either use the example provided to try out the Jira integration or follow along with your own application. + +1. You need an issue in your Jira account that you want to link to your Codefresh pipeline. If you do not have one yet, please create an issue. (Note that the project type and who is creating the issue etc. does not matter.) Alternatively, you can also create an issue first with the Jira step. However, this is not explained in this example. + +2. Next, add the following step to your Codefresh pipeline. In case that you are using the example, the [codefresh.yml](https://github.com/codefresh-contrib/jira-demo-app/blob/master/codefresh.yml) file is already added. + +{% highlight yaml %} + JiraCommentCreate: + title: "Add Jira Comment" + type: "jira-issue-manager" + stage: "deploy" + arguments: + JIRA_BASE_URL: '${{JIRA_BASE_URL}}' + JIRA_USERNAME: '${{JIRA_USERNAME}}' + JIRA_API_KEY: '${{JIRA_API_KEY}}' + JIRA_ISSUE_SOURCE_FIELD: '${{JIRA_ISSUE_SOURCE_FIELD}}' + ACTION: "comment_create" + COMMENT_BODY: "Build number ${{CF_BUILD_URL}} finished in Codefresh" +{% endhighlight yaml %} + +Let's look in detail at this step. +- Everything up to the arguments is similar to other Codefresh steps. + +These arguments are required to use the step: +- `JIRA_BASE_URL`: This is the url of your organisation e.g. 'https://company-name.atlassian.net' +- `JIRA_USERNAME`: This is usually the e-mail that you are logged in with at Jira +- `JIRA_API_KEY`: Note that you will have to create this key. The official [Atlassian documentation](https://confluence.atlassian.com/cloud/api-tokens-938839638.html) details how it can be created. + +Then we added these arguments for our specific step: +- `JIRA_ISSUE_SOURCE_FIELD`: This is the tag that identifies your issue e.g. MKTG-102 +- Within the comment, we are using a [Codefresh native variable](https://codefresh.io/docs/docs/codefresh-yaml/variables/) `CF_BUILD_URL`, which will reference your pipeline build and will allow you to search for your pipeline. + +All variables use the Codefresh specific variable notation ${% raw %}`{{MY_VARIABLE_EXAMPLE}}`{% endraw %}`. + +Since it is a new stage in your Codefresh pipeline, you want to add it at the top to your stages, e.g.: + +{% highlight yaml %} + stages: + - "clone" + - "build" + - "JiraCommentCreate" +{% endhighlight yaml %} + +Note that you can [provide the variables]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) needed for the Jira step directly in the shared configuration. The benefits are: +* You do not have to post sensitive information, such as the API key, directly in the codefresh.yml. +* If you use the same step across multiple pipelines, you don't have to copy-paste the same variables. + +Once you run the pipeline, you should be able to see the following output or similar + +{% include image.html +lightbox="true" +file="/images/integrations/jira/codefreshpipeline.png" +url="/images/integrations/jira/codefreshpipeline.png" +alt="Pipeline with Jira integration" +max-width="80%" +%} + +And the comment, including the URL to the pipeline, should be added to your Jira issue: + +{% include image.html +lightbox="true" +file="/images/integrations/jira/jira-comment.png" +url="/images/integrations/jira/jira-comment.png" +alt="Comment in Jira" +max-width="80%" +%} + +## What to read next + +* [Sending notifications to Slack]({{site.baseurl}}/docs/yaml-examples/examples/sending-the-notification-to-slack/) +* Have a look at other things that you can do with your Codefresh Pipeline in the [example section]({{site.baseurl}}/docs/yaml-examples/examples/) +* [Create a pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) diff --git a/_docs/example-catalog/sending-the-notification-to-slack.md b/_docs/example-catalog/sending-the-notification-to-slack.md new file mode 100644 index 00000000..63e1254b --- /dev/null +++ b/_docs/example-catalog/sending-the-notification-to-slack.md @@ -0,0 +1,45 @@ +--- +title: "Sending a notification to Slack" +description: "Connect your Codefresh pipelines to Slack" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/sending-the-notification-to-slack/ +toc: true +--- + +There are many ways to integrate slack with Codefresh + +1. You can use the [global slack integration]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) +1. You can use individual pipeline plugins such [slack-message-sender](https://codefresh.io/steps/step/slack-message-sender) and [slack-notifier](https://codefresh.io/steps/step/slack-notifier) +1. You use can simple POST requests with Curl (explained in this page) + +## Custom webhook to Slack + +Use a container image with a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) such as `byrnedo/alpine-curl` to send a notification to a Slack channel. + +{:start="1"} +1. Get the {% raw %}```${{SLACK_WEB_URL}}```{% endraw %} and put it in the Environment Variables or use [shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) + +{{site.data.callout.callout_info}} +You can find how to integrate with slack here [https://api.slack.com/incoming-webhooks](https://api.slack.com/incoming-webhooks){:target="_blank"} +{{site.data.callout.end}} + +{:start="2"} +2. Add the following step to your `codefresh.yml`: + + `slack step` +{% highlight yaml %} +slack_notify: + image: byrnedo/alpine-curl # curlimages/curl, or any other curl image + commands: + - curl -X POST --data-urlencode 'payload={"text":"Test slack integration via yaml"}' {% raw %}${{SLACK_WEB_URL}}{% endraw %} +{% endhighlight %} + + +## What to read next + +* [Global Slack Integration]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) +* [Advanced Workflows]({{site.baseurl}}/docs/codefresh-yaml/advanced-workflows/) +* [Pipeline Hooks]({{site.baseurl}}/docs/codefresh-yaml/hooks/) +* [Shared Configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) \ No newline at end of file diff --git a/_docs/example-catalog/shared-volumes-between-builds.md b/_docs/example-catalog/shared-volumes-between-builds.md new file mode 100644 index 00000000..9658a27e --- /dev/null +++ b/_docs/example-catalog/shared-volumes-between-builds.md @@ -0,0 +1,117 @@ +--- +title: "Sharing data between pipeline steps" +description: "How to cache folders between steps and builds" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/shared-volumes-between-builds/ +toc: true +--- + +Codefresh creates a [shared volume]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) in each pipeline that is automatically shared on all freestyle steps. + +{% 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%" +%} + +This volume exists at `/codefresh/volume` by default. You can simply copy files there to have them available in all Codefresh steps (as well as subsequent builds of the same pipeline) + +>Notice that the [git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) will delete any files **not** mentioned in `.gitignore`. Therefore if you want to cache a folder that exists in your project directory (such as `node_modules`) you also need to add it to `.gitignore` + +## Using the shared volume + +You can see the example project at [https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds](https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds). The repository contains a simple application, a Dockerfile and an example pipeline that saves/reads a dummy file to the Codefresh volume + + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "shared-volume" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefreshdemo/cf-example-shared-volumes-between-builds" + revision: "master" + stage: "clone" + + build_image: + title: "Building image" + type: "build" + image_name: "sample-app" + working_directory: "${{clone}}" + tag: "demo" + dockerfile: "Dockerfile" + stage: "build" + + copy_to_shared_volume: + title: "Copy file to shared volume" + type: "freestyle" + image: alpine:3.9 + working_directory: "${{clone}}" + commands: + - ls -l /codefresh/volume/ + - cp ./artifact/artifact.example /codefresh/volume/artifact.example + stage: "shared-volume" + + list_shared_volume: + title: "List shared volume files" + type: "freestyle" + image: alpine:3.9 + working_directory: "${{clone}}" + commands: + - pwd + - ls -l /codefresh/volume + stage: "shared-volume" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Builds a docker image using a [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +1. Copies the file `artifact.example` to the volume with a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +1. Reads the contents of the volume in a different [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + +If you run the pipeline you will see the file contents in the fourth step: + +{% include +image.html +lightbox="true" +file="/images/examples/shared-workspace/volume-list.png" +url="/images/examples/shared-workspace/volume-list.png" +alt="Listing volume contents" +caption="Listing volume contents" +max-width="80%" +%} + + +If you also run the pipeline a second time, you will see the dummy file in all steps (as the volume is automatically cached for subsequent builds as well). + + +## Caching build dependencies and Docker layers + +More information about caching build dependencies can be found in the [caching documentation page]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) as well as [in this blog post](https://codefresh.io/blog/caching-build-dependencies-codefresh-volumes/). + + +## What to read next + +* [Introduction to Codefresh pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) +* [Pipeline caching]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipeline-caching/) +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + + diff --git a/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md b/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md new file mode 100644 index 00000000..63e98467 --- /dev/null +++ b/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md @@ -0,0 +1,52 @@ +--- +title: "Shared volumes of service from composition step for other yml steps" +description: "How to share data in compositions" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/shared-volumes-of-service-from-composition-step-for-other-yml-steps/ +toc: true +--- +Using this repository, we'll help you get up to speed with basic functionality such as: building Docker images and use the shared volumes feature. + +This project uses Node Js to build an application which will eventually become a distributable Docker image. +If you want to share volumes of service in composition step for other yml steps you can use the variable {% raw %}```${{CF_VOLUME_NAME}}```{% endraw %}. It will refer to the volume that was generated for the specific flow. Can be used in conjunction with a composition to provide access to your cloned repository. + +{{site.data.callout.callout_info}} +##### Caching build dependencies + +More information about caching build dependencies you can find +[**HERE**](https://codefresh.io/blog/caching-build-dependencies-codefresh-volumes/){:target="_blank"} +{{site.data.callout.end}} + +## Looking around +In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +step_file_generation: + type: composition + composition: + version: '2' + services: + service1: + volumes: + - {% raw %}${{CF_VOLUME_NAME}}{% endraw %}:/codefresh/volume + image: {% raw %}${{build_step}}{% endraw %} + command: bash -c "echo hello > /codefresh/volume/myfile.txt" + composition_candidates: + test: + image: {% raw %}${{build_step}}{% endraw %} + command: echo hello +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [**repository**](https://github.com/codefreshdemo/cf-example-shared-volumes-composition-step){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +{{site.data.callout.callout_warning}} +The way the volume is shared between builds is that upon build completion we create an image of the volume state to be used in the next builds. If you run 2 builds in parallel from the same pipeline and at the same time, each will use the same last volume image, but it’ll run separately on both. The volume image you’ll get upon completion is the state of the build that finished last. +{{site.data.callout.end}} + diff --git a/_docs/example-catalog/spring-boot-kafka-zookeeper.md b/_docs/example-catalog/spring-boot-kafka-zookeeper.md new file mode 100644 index 00000000..675a1a5e --- /dev/null +++ b/_docs/example-catalog/spring-boot-kafka-zookeeper.md @@ -0,0 +1,198 @@ +--- +title: "Spring Boot + Kafka + Zookeeper" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/spring-boot-kafka-zookeeper/ + - /docs/on-demand-test-environment/example-compositions/spring-boot-kafka-zookeeper/ +toc: true +--- +This project uses `Java, Spring Boot, Kafka, Zookeeper` to show you how to integrate these services in the composition. + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/example-springboot-kafka){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Zookeeper Docker image + +Kafka uses ZooKeeper so you need to first start a ZooKeeper server if you don't already have one + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} + zookeeper: + image: wurstmeister/zookeeper + ports: + - "2181:2181" +{% endraw %} +{% endhighlight %} + +## Kafka Docker image +Now start the Kafka server. In the `docker-compose.yml` it can be something like this + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} + kafka: + build: + context: kafka + dockerfile: Dockerfile + links: + - zookeeper:zk + ports: + - "9092:9092" + environment: + KAFKA_ADVERTISED_HOST_NAME: $CF_HOST_IP + KAFKA_ZOOKEEPER_CONNECT: zk:2181 + KAFKA_MESSAGE_MAX_BYTES: 2000000 + KAFKA_CREATE_TOPICS: "Topic1:1:1" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - zookeeper +{% endraw %} +{% endhighlight %} + +To start the Kafka server with the certain per-configuration, you need to use Environment variables. Below, you can see which Environment variables are available for this service. + +__Broker IDs__ + +You can configure the broker id in different ways: + +1. Explicitly, using ```KAFKA_BROKER_ID``` +2. Via a command, using ```BROKER_ID_COMMAND```, e.g. ```BROKER_ID_COMMAND: "hostname | awk -F'-' '{print $2}'"``` + +If you don't specify a broker id in your docker-compose file, it will automatically be generated (see [https://issues.apache.org/jira/browse/KAFKA-1070](https://issues.apache.org/jira/browse/KAFKA-1070){:target="_blank"}. This allows scaling up and down. In this case it is recommended to use the ```--no-recreate``` option of docker-compose to ensure that containers are not re-created and thus keep their names and ids. + + +__Automatically create topics__ + +If you want to have kafka-docker automatically create topics in Kafka during +creation, a ```KAFKA_CREATE_TOPICS``` environment variable can be +added in ```docker-compose.yml```. + +Here is an example snippet from ```docker-compose.yml```: + + environment: + KAFKA_CREATE_TOPICS: "Topic1:1:3,Topic2:1:1:compact" + +```Topic 1``` will have 1 partition and 3 replicas, ```Topic 2``` will have 1 partition, 1 replica and a `cleanup.policy` set to `compact`. + +__Advertised hostname__ + +You can configure the advertised hostname in different ways: + +1. Explicitly, using ```KAFKA_ADVERTISED_HOST_NAME``` +2. Via a command, using ```HOSTNAME_COMMAND```, e.g. ```HOSTNAME_COMMAND: "route -n | awk '/UG[ \t]/{print $$2}'"``` + +When using commands, make sure you review the "Variable Substitution" section in [https://docs.docker.com/compose/compose-file/](https://docs.docker.com/compose/compose-file/){:target="_blank"} + +If ```KAFKA_ADVERTISED_HOST_NAME``` is specified, it takes precedence over ```HOSTNAME_COMMAND``` + +For AWS deployment, you can use the Metadata service to get the container host's IP: +``` +HOSTNAME_COMMAND=wget -t3 -T2 -qO- http://169.254.169.254/latest/meta-data/local-ipv4 +``` +Reference: [http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html){:target="_blank"} + +__JMX__ + +For monitoring purposes, you may wish to configure JMX. Additional to the standard JMX parameters, problems could arise from the underlying RMI protocol used to connect + +* java.rmi.server.hostname - interface to bind listening port. +* com.sun.management.jmxremote.rmi.port - the port to service RMI requests. + +For example, to connect to a kafka running locally (assumes exposing port 1099) + + KAFKA_JMX_OPTS: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.rmi.port=1099" + JMX_PORT: 1099 + +## Spring Boot + Kafka +Then grab the spring-kafka JAR and all of its dependencies - the easiest way to do that is to declare a dependency in your build tool, e.g. for Maven: + + `Text` +{% highlight xml %} +{% raw %} + + org.springframework.kafka + spring-kafka + ${spring-kafka.version} + + + org.springframework.kafka + spring-kafka-test + ${spring-kafka.version} + test + +{% endraw %} +{% endhighlight %} + +Using plain Java to send and receive a message: + + `Java` +{% highlight java %} +{% raw %} +private static String BOOT_TOPIC = "boot.t"; + +@Autowired +private Sender sender; + +@Autowired +private Receiver receiver; + +@ClassRule +public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, BOOT_TOPIC); + +@BeforeClass +public static void setUpBeforeClass() throws Exception { + System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString()); +} + +@Test +public void testReceive() throws Exception { + sender.send(BOOT_TOPIC, "Hello Boot!"); + + receiver.getLatch().await(10000, TimeUnit.MILLISECONDS); + assertThat(receiver.getLatch().getCount()).isEqualTo(0); +} +{% endraw %} +{% endhighlight %} + +Maven will download the needed dependencies, compile the code and run the unit test case. The result should be a successful build during which following logs are generated: + + `Java` +{% highlight java %} +{% raw %} +. ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: (v1.5.2.RELEASE) + +08:36:56.175 [main] INFO c.c.kafka.SpringKafkaApplicationTest - Starting SpringKafkaApplicationTest on cnf-pc with PID 700 (started by CodeNotFound in c:\code\st\spring-kafka\spring-kafka-avro) +08:36:56.175 [main] INFO c.c.kafka.SpringKafkaApplicationTest - No active profile set, falling back to default profiles: default +08:36:56.889 [main] INFO c.c.kafka.SpringKafkaApplicationTest - Started SpringKafkaApplicationTest in 1.068 seconds (JVM running for 5.293) +08:36:58.223 [main] INFO c.codenotfound.kafka.producer.Sender - sending user='{"name": "John Doe", "favorite_number": null, "favorite_color": "green"}' +08:36:58.271 [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-L-1] INFO c.c.kafka.consumer.Receiver - received user='{"name": "John Doe", "favorite_number": null, "favorite_color": "green"}' +08:37:00.240 [main] ERROR o.a.zookeeper.server.ZooKeeperServer - ZKShutdownHandler is not registered, so ZooKeeper server won't take any action on ERROR or SHUTDOWN server state changes +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.871 sec - in com.codenotfound.kafka.SpringKafkaApplicationTest + +Results: + +Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 + +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 41.632 s +[INFO] Finished at: 2017-04-17T08:37:31+02:00 +[INFO] Final Memory: 18M/212M +[INFO] ------------------------------------------------------------------------ +{% endraw %} +{% endhighlight %} + diff --git a/_docs/example-catalog/terraform.md b/_docs/example-catalog/terraform.md new file mode 100644 index 00000000..40de1d73 --- /dev/null +++ b/_docs/example-catalog/terraform.md @@ -0,0 +1,114 @@ +--- +title: "Deploy with Terraform" +description: "Use Terraform in a Codefresh pipeline with Docker" +group: yaml-examples +sub_group: examples +toc: true +--- + +[Terraform](https://www.terraform.io/) is a platform for *Infrastructure as Code*. It allows you to describe your cloud infrastructure in a declarative manner. + +You can use Terraform to deploy to Kubernetes or any other supported cloud platform. Because Terraform itself is already offered [in a Docker container](https://hub.docker.com/r/hashicorp/terraform/), it is very easy to run Terraform in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/terraform/terraform-pipeline.png" +url="/images/examples/terraform/terraform-pipeline.png" +alt="Running Terraform inside Codefresh" +caption="Running Terraform inside Codefresh" +max-width="80%" +%} + +## The example Terraform project + +You can see the example project at [https://github.com/codefresh-contrib/terraform-sample-app](https://github.com/codefresh-contrib/terraform-sample-app). The repository contains a simple Terraform definition that creates a VM on Google cloud. + +You can play with it locally after installing the `terraform` executable. + +## Prerequisites + +You need to [create a Codefresh account]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/) and a Google account first. Then you need to create a [Service account Key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) which will allow terraform to communicate with Google cloud. + + +Add your service account json as a pipeline variable called `ACCOUNT_JSON_CONTENT`. The content of this variable will be used +in order to authenticate to Google cloud. + +## Create a CI/CD pipeline for Terraform + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - prepare + - deploy +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/terraform-sample-app' + revision: master + git: github + SetupAuth: + image: alpine:3.9 + title: Setting up Google cloud auth + stage: prepare + commands: + - echo $ACCOUNT_JSON_CONTENT > /codefresh/volume/account.json + - cf_export GOOGLE_CLOUD_KEYFILE_JSON=/codefresh/volume/account.json + DeployWithTerraform: + image: hashicorp/terraform:0.12.0 + title: Deploying Terraform plan + stage: deploy + commands: + - terraform init + - terraform apply -auto-approve + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +1. Runs [cf_export]({{site.baseurl}}/docs/codefresh-yaml/variables/#exporting-environment-variables-from-a-freestyle-step) to create a pipeline variable with the path of the google service account +1. Runs `terraform init/apply` to create the VM on Google cloud + +>For simplicity, we auto-approve the terraform plan in the example pipeline. In a production pipeline you would instead use an [approval step ]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) to inspect the plan, before actually applying it. + +The pipeline needs a [single environment variable]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) that holds the content of the service account. + + +{% include image.html +lightbox="true" +file="/images/examples/terraform/google_cloud_json.png" +url="/images/examples/terraform/google_cloud_json.png" +alt="Passing the Google account in the pipeline parameters" +caption="Passing the Google account in the pipeline parameters" +max-width="60%" +%} + + +Run the pipeline and see your deployment succeed. + + +Note that in a production pipeline you should also handle the [Terraform state](https://www.terraform.io/docs/state/) in a proper manner. The example provided is using a file for [state storage](https://www.terraform.io/docs/backends/index.html) which is not appropriate when using Terraform in a team environment. Instead you should use one of the [storage backends](https://www.terraform.io/docs/backends/types/index.html) that support High Availability and Locking. + + + + +## Handling Pull requests + +You can easily use the same pipeline or a different one for pull requests. In this case replace the `terraform apply` command with `terraform plan`. Even better, you can add an [approval step]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/) to allow humans to inspect the pipeline first. + + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/transferring-php-ftp.md b/_docs/example-catalog/transferring-php-ftp.md new file mode 100644 index 00000000..5b8d513f --- /dev/null +++ b/_docs/example-catalog/transferring-php-ftp.md @@ -0,0 +1,118 @@ +--- +title: "Transferring Applications via FTP" +description: "Deploying a Php Application to a VM using FTP" +group: yaml-examples +sub_group: examples +toc: true +redirect_from: + - /docs//learn-by-example/java/spring-mvc-jdbc-template/ +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A remote machine with an ftp server and ssh setup (ensure that your ftp directory, I.e., `/srv/ftp/pub` has the proper write permissions for the ftp user) + +>Note that as you may already know, FTP is extremely insecure as it relies on plain-text passwords and usernames, making data very vulnerable to sniffing. A more secure solution would be to use SFTP or SCP. + +## The Example Php Project + +The example project can be found on [GitHub](https://github.com/codefresh-contrib/ftp-php-app). The application is a simple Php application that displays an example timer. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/test-environment.png" +url="/images/learn-by-example/php/test-environment.png" +alt="Example Php Application" +caption="Example Php Application" +max-width="90%" +%} + +## Create the Pipeline + +Our pipeline will contain four stages: + +- A stage for cloning +- A stage for packaging +- A stage for transferring files + +{% include image.html +lightbox="true" +file="/images/examples/php-file-transfer/pipeline.png" +url="/images/examples/php-file-transfer/pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +Here is the entire pipeline: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/yaml-examples/examples/ + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "install" + - "transfer" +steps: + clone: + title: "Cloning main repository..." + type: "git-clone" + arguments: + repo: "codefresh-contrib/ftp-php-app" + git: "github" + stage: "clone" + install_dependencies: + title: "Collecting Php dependencies..." + type: "freestyle" + working_directory: "./ftp-php-app" + arguments: + image: "composer:1.9.3" + commands: + - "composer install --ignore-platform-reqs --no-interaction --no-plugins --no-scripts --prefer-dist" + stage: "install" + steps: + ftp_transfer: + title: "Transferring application to VM via ftp..." + type: "freestyle" + working_directory: "./ftp-php-app" + arguments: + image: "dockito/lftp-client:latest" + environment: + - USER= + - PASSWORD= + - HOST= + - PUB_FTP_DIR= + commands: + - lftp -e "set ftp:use-site-utime2 false; mirror -x ^\.git/$ -X flat-logo.png -p -R ftp-php-ap $PUB_FTP_DIR/ftp-php-app; exit" -u $USER,$PASSWORD $HOST + stage: "transfer" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that installs the necessary Php dependencies for our application +3. A freestyle step that transfers our application via ftp. Note that you will need to change the environment variables to your respective values, either in the YAML itself (above), or through the pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/php-file-transfer/variables.png" +url="/images/examples/php-file-transfer/variables.png" +alt="Codefresh Enbironment Variables" +caption="Codefresh Enbironment Variables" +max-width="90%" +%} + +## What to Read Next + +- [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) + + diff --git a/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md b/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md new file mode 100644 index 00000000..95f914eb --- /dev/null +++ b/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md @@ -0,0 +1,135 @@ +--- +title: "Trigger a Kubernetes Deployment from a Dockerhub Push Event" +description: "Learn how to trigger a Kubernetes deployment when an image is updated" +group: yaml-examples +sub_group: examples +toc: true +--- + +In this example, we will cover how to trigger a Kubernetes deployment from a Dockerhub Push event using a Dockerhub [registry trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger). + +Our example will have two pipelines. One that is responsible for packaging code (CI), and the other will be responsible for deploying code (CD). + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A DockerHub registry [connected to your Codefresh account]({{site.baseurl}}/docs/docker-registries/external-docker-registries/docker-hub/) +- A Kubernetes cluster [connected to your Codefresh account]({{site.baeurl}}/docs/deploy-to-kubernetes/add-kubernetes-cluster/) +- A service for your application [deployed to your cluster]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/#viewing-your-kubernetes-services) + +## The Example Project + +You can see the example project on [GitHub](https://github.com/codefresh-contrib/registry-trigger-sample-app/tree/master). The repository contains a simple Hello World NodeJs app as well as 2 pipelines. + +## Create the CI Pipeline + +As mentioned before, our first pipeline will handle the CI process. There will be 3 stages: + +- A stage for cloning +- A stage for building the image +- A stage for pushing the image to DockerHub + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-deployment-ci-pipeline.png" +url="/images/examples/deployments/k8s-deployment-ci-pipeline.png" +alt="Codefresh UI CI Pipeline View" +caption="Codefresh UI CI Pipeline View" +max-width="90%" +%} + + `codefresh-CI-pipeline.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' + +stages: +- checkout +- build +- push + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + arguments: + repo: 'codefresh-contrib/registry-trigger-sample-app' + revision: 'master' + git: github + build_my_app: + title: Building image... + type: build + stage: build + arguments: + image_name: registry-trigger-sample-app + working_directory: ${{clone}} + tag: 'master' + dockerfile: Dockerfile + push_to_my_registry: + stage: 'push' + type: push + title: Pushing to Dockerhub... + arguments: + candidate: ${{build_my_app}} + tag: 'latest' + registry: dockerhub + image_name: annabaker/registry-trigger-sample-app +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +2. Builds a docker image tagged with the Application version using a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) +3. Pushes the Docker image using a [Push step](https://codefresh.io/docs/docs/codefresh-yaml/steps/push/) to the DockerHub registry you have integrated with Codefresh. + +## Create the CD Pipeline + +This pipeline will only contain one stage/step, for deploying. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-deployment-CD-pipeline.png" +url="/images/examples/deployments/k8s-deployment-CD-pipeline.png" +alt="Codefresh UI CD Pipeline View" +caption="Codefresh UI CD Pipeline View" +max-width="90%" +%} + +Note that for the trigger mechanism to take place, you will need to [add a DockerHub registry trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger) to the pipeline. + + `codefresh-CD-pipeline.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "deploy" + +steps: + deploy_to_k8s: + title: Running Deploy Script... + type: deploy + kind: kubernetes + arguments: + cluster: anna-demo@FirstKubernetes + namespace: default + service: registry-trigger-sample-app + candidate: + image: annabaker/registry-trigger-sample-app:latest + registry: 'dockerhub' +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Uses a [Deploy step]({{site.baseurl}}/docs/codefresh-yaml/steps/deploy/) to deploy the image to Kubernetes. The deploy step uses a [Registry trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger) to kick off the pipeline when the updated image is pushed to the registry. + +## What to read next + +* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) +* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) +* [Pipeline plugins](https://codefresh.io/steps/) +* [Triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/) diff --git a/_docs/example-catalog/uploading-or-downloading-from-gs.md b/_docs/example-catalog/uploading-or-downloading-from-gs.md new file mode 100644 index 00000000..a9b00bfd --- /dev/null +++ b/_docs/example-catalog/uploading-or-downloading-from-gs.md @@ -0,0 +1,153 @@ +--- +title: "Uploading/Downloading Files to/from Google Storage" +description: "Upload and download a jar from Google Storage from within a pipeline" +group: yaml-examples +sub_group: examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A [Google Storage Bucket](https://cloud.google.com/storage/docs/creating-buckets) with public read access +- A private key [downloaded](https://cloud.google.com/storage/docs/authentication#gsutilauth) for the existing service account associated with your bucket (for this example, we base64 encoded the key for ease of use in a pipeline variable using `base64 key_file.json > key_file.b64`) + +## The Example Project + +The example project can be found on [GitHub](https://github.com/codefresh-contrib/gcloud-storage-sample-app.git). The application is a simple Scala Hello World application contained in a jar, with a dependency on a scala-library jar which we will download from the bucket and package into a Docker image. + +Our project will contain two pipelines, one for uploading the dependency jar to our bucket, and the other for downloading the jar from the bucket. + +## Create the First Pipeline + +The first pipeline will contain one stage/step, a step for uploading the jar to the Google Storage Bucket. + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-upload-pipeline.png" +url="/images/examples/gs/gs-upload-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +You will need to define a pipeline variable, KEY_FILE, in the pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-pipeline-vars.png" +url="/images/examples/gs/gs-pipeline-vars.png" +alt="Codefresh UI Pipeline Variables" +caption="Codefresh UI Pipeline Variables" +max-width="90%" +%} + +Here is the first pipeline: + +`codefresh-upload.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "upload" + +steps: + upload: + title: "Uploading library jar to GS..." + type: "freestyle" + stage: "upload" + arguments: + image: "google/cloud-sdk:slim" + commands: + - echo $KEY_FILE | base64 --decode > key_file.json + - gcloud auth activate-service-account --key-file=key_file.json + - curl https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.2/scala-library-2.12.2.jar | gsutil cp - gs://anna-demo-bucket/scala-library-2.12.2.jar +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that uploads a jar from Maven into our Google Storage bucket. + +## Create the Second Pipeline + +Our second pipeline will have four stages: + +- A stage for cloning the repository +- A stage for downloading the jar from the bucket +- A stage for building the image +- A stage for pushing the image to the repository + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-download-pipeline.png" +url="/images/examples/gs/gs-download-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +Here is the YAML for the second pipeline: + +`codefresh-download.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "clone" + - "download" + - "build" + - "push" + +steps: + clone: + title: "Cloning main repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/gcloud-storage-sample-app" + git: "github" + revision: "master" + download: + title: "Downloading dependency lib from GS..." + type: "freestyle" + stage: "download" + working_directory: ${{clone}} + arguments: + image: "google/cloud-sdk:slim" + commands: + - gsutil cp gs://anna-demo-bucket/scala-library-2.12.2.jar . + build: + title: "Building docker image..." + type: "build" + stage: "build" + working_directory: ${{clone}} + arguments: + image_name: "annabaker/gcloud-storage-sample-app" + tag: "master" + push_to_my_registry: + stage: "push" + type: "push" + title: "Pushing to external registry..." + arguments: + candidate: ${{build}} + tag: '1.0.0' + registry: "dockerhub" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/). +2. A [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) that downloads the dependency jar from our publicly-accessible Google Storage bucket. +3. Builds a docker image using a [build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/). +4. Pushes the Docker image using a [Push step](https://codefresh.io/docs/docs/codefresh-yaml/steps/push/) to the DockerHub registry you have integrated with Codefresh. + +## What to Read Next + +- [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Build step]({{site.baseurl}}/docs/codefresh-yaml/steps/build/) diff --git a/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md b/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md new file mode 100644 index 00000000..4a09761d --- /dev/null +++ b/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md @@ -0,0 +1,36 @@ +--- +title: "Use kubectl as part of Freestyle step" +description: "How to run manually kubectl in a Codefresh pipeline" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/use-kubectl-as-part-of-freestyle-step/ +toc: true +--- + + +Running Kubernetes commands in Codefresh as part of the workflow is very easy. + + +Codefresh is adding all your clusters into the workflow ready to be used as part of your CI/CD pipeline. +The context remains the same as it appears in the [Codefresh Kubernetes dashboard]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/). + +>If your cluster name includes spaces then make sure that you use quotes in the `kubectl` command. + +* Use image: `codefresh/kubectl` +* Add your commands: + * `kubectl config get-contexts`. Will print the cluster that we added to the workflow + * `kubectl config use-context "my-cluster-name"`. The name is the same as in `Account settings` → `Integrations` → `Kubernetes` + * `kubectl get po -owide` + * `kubectl get nodes` + + +## Follow the example + +* Add this [Git repo](https://github.com/Codefresh-Examples/kubectl-in-freestyle-step){:target="_blank"} to your account +* Change the pipeline configuration to use `codefresh.yml`. +* Build. + +## Running parallel steps with kubectl + +More complex examples can be found in the [custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) documentation page. diff --git a/_docs/example-catalog/vault-secrets-in-the-pipeline.md b/_docs/example-catalog/vault-secrets-in-the-pipeline.md new file mode 100644 index 00000000..7344ce06 --- /dev/null +++ b/_docs/example-catalog/vault-secrets-in-the-pipeline.md @@ -0,0 +1,116 @@ +--- +title: "Vault Secrets in the Pipeline" +description: "Accessing and Referring to Vault Secrets in the Pipeline" +group: yaml-examples +sub_group: examples +toc: true +--- + +Codefresh offers a Vault plugin you may use from the [Step Marketplace](https://codefresh.io/steps/step/vault). The plugin imports key-value pairs from the Vault server, and exports them into the pipeline. +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- An existing Vault server [already setup](https://learn.hashicorp.com/vault/getting-started/install) +- A secret stored in said Vault server with a key of "password" +- A Vault [authorization token](https://learn.hashicorp.com/vault/getting-started/authentication#tokens) + +## The Example Java Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/vault-sample-app). + +The example application retrieves the system variable "password," from the pipeline and uses it to authenticate to a Redis database, but you are free to use any type of database of your choosing. + +```java + String password = System.getenv("password"); + String host = System.getProperty("server.host"); + + RedisClient redisClient = new RedisClient( + RedisURI.create("redis://" + password + "@" + host + ":6379")); + RedisConnection connection = redisClient.connect(); +``` + +Also in the example application is a simple unit test that ensures we are able to read and write data to the database. + +You cannot run the application locally, as it needs to run in the pipeline in order to use our environment variables to connect. + +## Create the Pipeline + +We will be running the following pipeline that contains three step types: a vault step, a [git-clone]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) step, and a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). + +{% include image.html +lightbox="true" +file="/images/examples/secrets/vault-pipeline.png" +url="/images/examples/secrets/vault-pipeline.png" +alt="Vault pipeline" +caption="Vault Pipeline" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the `VAULT_ADDR`, `VAULT_AUTH`, and `VAULT_AUTH_TOKEN` arguments under the first step to your respective values. + +`codefresh.yml` +```yaml +version: "1.0" +stages: + - "vault" + - "clone" + - "package" +steps: + vault: + title: Importing vault values... + stage: "vault" + type: vault + arguments: + VAULT_ADDR: 'http://:' + VAULT_PATH: 'path/to/secret' + VAULT_AUTH_TOKEN: '' + clone: + title: Cloning main repository... + type: git-clone + arguments: + repo: 'codefresh-contrib/vault-sample-app' + git: github + stage: clone + package_jar: + title: Packaging jar and running unit tests... + stage: package + working_directory: ${{clone}} + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dserver.host=my-redis-db-host clean package + services: + composition: + my-redis-db-host: + image: 'redis:4-alpine' + command: 'redis-server --requirepass $password' + ports: + - 6379 +``` + +The above pipeline does the following: + +1. Imports the key-value pairs from the Vault server and exports them into the pipeline under `/meta/env_vars_to_export`. +2. Clones the main repository (note the special use of naming the step `main_clone`). This ensures that all subsequent commands are run [inside the project that was checked out]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/#basic-clone-step-project-based-pipeline). +3. The last step, `package_jar`, does a few special things to take note of: + - Spins up a [Service Container]({{site.baseurl}}/docs/codefresh-yaml/service-containers/) running Redis on port 6379 , and sets the password to the database using our exported environment variable + - Sets `maven.repo.local` to cache Maven dependencies into the local codefresh volume to [speed up builds]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/#caching-the-maven-dependencies) + - Runs unit tests and packages the jar. Note how you can directly refer to the service container's name (`my-redis-db-host`) when we set `server.host` + +You will see that the variable was correctly exported to the pipeline by running a simple `echo` command: + {% include image.html + lightbox="true" + file="/images/examples/secrets/vault-pipeline2.png" + url="/images/examples/secrets/vault-pipeline2.png" + alt="Vault pipeline Variable" + caption="Vault Pipeline Variable" + max-width="100%" + %} + +## What to Read Next + +- [Git-clone Step]({{site.baseurl}}/docs/codefresh-yaml/steps/git-clone/) +- [Freestyle Step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/) +- [Service Containers]({{site.baseurl}}//docs/codefresh-yaml/service-containers/) diff --git a/_docs/example-catalog/web-terminal.md b/_docs/example-catalog/web-terminal.md new file mode 100644 index 00000000..d99308da --- /dev/null +++ b/_docs/example-catalog/web-terminal.md @@ -0,0 +1,42 @@ +--- +title: "Web terminal" +description: "" +group: yaml-examples +sub_group: examples +redirect_from: + - /docs/web-terminal/ + - /docs/on-demand-test-environment/example-compositions/web-terminal/ +toc: true +--- +This example shows you how to access containers running in a Codefresh standup environment. + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Here are the contents of this file: + + `Composition.yml` +{% highlight yaml %} +version: '3' +services: + my-service: + image: 'containers101/whomi:master' + volumes: + - my-service:/app + ports: + - '1337' + terminal: + image: 'containers101/cfterminal:master' + ports: + - '8000' + volumes_from: + - my-service +volumes: + my-service: + driver: local +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-web-termial){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} From ff47845fba2262f11e807e1af4e799dc065ec991 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 10:57:47 +0200 Subject: [PATCH 02/17] Update nav and home yamls Added example topics to home and nav yamls --- _data/nav.yml | 136 ++++++++++++++++++ _docs/example-catalog/{ci-examples => }/cc.md | 0 .../{ci-examples => }/general.md | 0 .../general/selenium-test.md | 0 .../{ci-examples => }/golang.md | 0 .../example-catalog/{ci-examples => }/java.md | 0 .../{ci-examples => }/mobile/android.md | 0 .../{ci-examples => }/nodejs.md | 0 .../{ci-examples => }/python.md | 0 .../{ci-examples => }/scala.md | 0 10 files changed, 136 insertions(+) rename _docs/example-catalog/{ci-examples => }/cc.md (100%) rename _docs/example-catalog/{ci-examples => }/general.md (100%) rename _docs/example-catalog/{ci-examples => }/general/selenium-test.md (100%) rename _docs/example-catalog/{ci-examples => }/golang.md (100%) rename _docs/example-catalog/{ci-examples => }/java.md (100%) rename _docs/example-catalog/{ci-examples => }/mobile/android.md (100%) rename _docs/example-catalog/{ci-examples => }/nodejs.md (100%) rename _docs/example-catalog/{ci-examples => }/python.md (100%) rename _docs/example-catalog/{ci-examples => }/scala.md (100%) diff --git a/_data/nav.yml b/_data/nav.yml index dc432643..ee41fe36 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -196,6 +196,142 @@ +- title: "Example catalog" + url: "/examples" + pages: + - title: "Git" + sub-pages: + - title: Checking out Git repositories + url: "/git-checkout" + - title: Custom Git commmands + url: "/git-checkout-custom" + - title: Non-Git checkouts + url: "/non-git-checkout" + - title: Use Git Hash in CI + url: "/get-short-sha-id-and-use-it-in-a-ci-process" + - title: "Image builds" + sub-pages: + - title: Build an Image with the Dockerfile in Root Directory + url: "/build-an-image-dockerfile-in-root-directory" + - title: Build an Image - Specify Dockerfile Location + url: "/build-an-image-specify-dockerfile-location" + - title: Build an Image from a Different Git Repository + url: "/build-an-image-from-a-different-git-repository" + - title: Build and Push an Image + url: "/build-and-push-an-image" + - title: Build an Image with Build Arguments + url: "/build-an-image-with-build-arguments" + - title: Sharing data between steps + url: "/shared-volumes-between-builds" + - title: Uploading/downloading from Google Storage buckets + url: "/uploading-or-downloading-from-gs" + - title: Calling other pipelines + url: "/call-child-pipelines" + - title: Trigger a K8s Deployment from a DockerHub Push Event + url: "/trigger-a-k8s-deployment-from-docker-registry" + - title: "Testing" + url: "/examples" + sub-pages: + - title: Run Unit Tests + url: "/run-unit-tests" + - title: Run Integration Tests + url: "/run-integration-tests" + - title: Fan-in/Fan-out Example with Unit Tests + url: "fan-in-fan-out" + - title: "Code Coverage" + url: "/examples" + sub-pages: + - title: Codecov Coverage Reports + url: "/codecov-testing" + - title: Coveralls Coverage Reports + url: "/coveralls-testing" + - title: Codacy Coverage Reports + url: "/codacy-testing" + - title: "Databases" + url: "/examples" + sub-pages: + - title: Run Integration Tests with Mongo + url: "/integration-tests-with-mongo" + - title: Run Integration Tests with MySQL + url: "/integration-tests-with-mysql" + - title: Run Integration Tests with PostgreSQL + url: "/integration-tests-with-postgres" + - title: Run Integration Tests with Redis + url: "/integration-tests-with-redis" + - title: Populate a database with existing data + url: "/populate-a-database-with-existing-data" + - title: Shared volumes for composition + url: "/shared-volumes-of-service-from-composition-step-for-other-yml-steps" + - title: Import data to MongoDB + url: "/import-data-to-mongodb" + - title: "Deployments" + url: "/examples" + sub-pages: + - title: Deploy to VM + url: "/packer-gcloud" + - title: Deploy to a VM using ftp + url: "/transferring-php-ftp" + - title: Deploy to Tomcat using SCP + url: "/deploy-to-tomcat-via-scp" + - title: Deploy with Helm + url: "/helm" + - title: Deploy with Terraform + url: "/terraform" + - title: Deploy with Pulumi + url: "/pulumi" + - title: Deploy to Nomad + url: "/nomad" + - title: Deploy to Heroku + url: "/deploy-to-heroku" + - title: Use kubectl as part of Freestyle step + url: "/use-kubectl-as-part-of-freestyle-step" + - title: Deploy with Kustomize + url: "/deploy-with-kustomize" + - title: Deploy to Docker Swarm + url: "/docker-swarm" + - title: Amazon ECS/Fargate + url: "/amazon-ecs" + - title: Elastic Beanstalk + url: "/elastic-beanstalk" + - title: "Secrets" + url: "/examples" + sub-pages: + - title: Vault Secrets in the Pipeline + url: "/vault-secrets-in-the-pipeline" + - title: Decryption with Mozilla SOPS + url: "/decryption-with-mozilla-sops" + - title: GitOps secrets + url: "/gitops-secrets" + - title: "Compositions" + url: "/examples" + sub-pages: + - title: Launch Composition + url: "/launch-composition" + - title: Use Docker compose + url: "/launching-a-composition-and-defining-a-service-environment-variables-using-a-file" + - title: "Notifications" + url: "/examples" + sub-pages: + - title: Sending the notification to Slack + url: "/sending-the-notification-to-slack" + - title: Sending the notification to Jira + url: "/sending-the-notification-to-jira" + - title: "Security" + url: "/examples" + sub-pages: + - title: Secure a Docker Container Using HTTP Basic Auth + url: "/secure-a-docker-container-using-http-basic-auth" + - title: "General" + url: "/examples" + sub-pages: + - title: NodeJS + Angular2 + MongoDB + url: "/nodejs-angular2-mongodb" + - title: Spring Boot + Kafka + Zookeeper + url: "/spring-boot-kafka-zookeeper" + - title: Web terminal + url: "/web-terminal" + + diff --git a/_docs/example-catalog/ci-examples/cc.md b/_docs/example-catalog/cc.md similarity index 100% rename from _docs/example-catalog/ci-examples/cc.md rename to _docs/example-catalog/cc.md diff --git a/_docs/example-catalog/ci-examples/general.md b/_docs/example-catalog/general.md similarity index 100% rename from _docs/example-catalog/ci-examples/general.md rename to _docs/example-catalog/general.md diff --git a/_docs/example-catalog/ci-examples/general/selenium-test.md b/_docs/example-catalog/general/selenium-test.md similarity index 100% rename from _docs/example-catalog/ci-examples/general/selenium-test.md rename to _docs/example-catalog/general/selenium-test.md diff --git a/_docs/example-catalog/ci-examples/golang.md b/_docs/example-catalog/golang.md similarity index 100% rename from _docs/example-catalog/ci-examples/golang.md rename to _docs/example-catalog/golang.md diff --git a/_docs/example-catalog/ci-examples/java.md b/_docs/example-catalog/java.md similarity index 100% rename from _docs/example-catalog/ci-examples/java.md rename to _docs/example-catalog/java.md diff --git a/_docs/example-catalog/ci-examples/mobile/android.md b/_docs/example-catalog/mobile/android.md similarity index 100% rename from _docs/example-catalog/ci-examples/mobile/android.md rename to _docs/example-catalog/mobile/android.md diff --git a/_docs/example-catalog/ci-examples/nodejs.md b/_docs/example-catalog/nodejs.md similarity index 100% rename from _docs/example-catalog/ci-examples/nodejs.md rename to _docs/example-catalog/nodejs.md diff --git a/_docs/example-catalog/ci-examples/python.md b/_docs/example-catalog/python.md similarity index 100% rename from _docs/example-catalog/ci-examples/python.md rename to _docs/example-catalog/python.md diff --git a/_docs/example-catalog/ci-examples/scala.md b/_docs/example-catalog/scala.md similarity index 100% rename from _docs/example-catalog/ci-examples/scala.md rename to _docs/example-catalog/scala.md From 4d685f0a8ff79a2fe3790012bbc3def808a0a2c8 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 13:58:17 +0200 Subject: [PATCH 03/17] Updates --- _data/nav.yml | 8 ++++---- _docs/example-catalog/amazon-ecs.md | 3 +-- .../build-an-image-from-a-different-git-repository.md | 4 ++-- .../build-an-image-specify-dockerfile-location.md | 2 +- .../build-an-image-with-build-arguments.md | 3 +-- ...uild-an-image-with-the-dockerfile-in-root-directory.md | 2 +- _docs/example-catalog/build-and-push-an-image.md | 2 +- _docs/example-catalog/call-child-pipelines.md | 2 +- _docs/example-catalog/cc.md | 2 +- _docs/example-catalog/cc/c-make.md | 2 +- _docs/example-catalog/cc/cpp-cmake.md | 2 +- _docs/example-catalog/codacy-testing.md | 2 +- _docs/example-catalog/codecov-testing.md | 2 +- _docs/example-catalog/coveralls-testing.md | 2 +- _docs/example-catalog/decryption-with-mozilla-sops.md | 2 +- _docs/example-catalog/deploy-to-heroku.md | 2 +- _docs/example-catalog/deploy-to-tomcat-via-scp.md | 2 +- _docs/example-catalog/deploy-with-kustomize.md | 2 +- _docs/example-catalog/docker-swarm.md | 2 +- _docs/example-catalog/dotnet.md | 2 +- _docs/example-catalog/elastic-beanstalk.md | 2 +- _docs/example-catalog/examples.md | 2 +- _docs/example-catalog/fan-in-fan-out.md | 2 +- _docs/example-catalog/general.md | 2 +- _docs/example-catalog/general/selenium-test.md | 2 +- .../get-short-sha-id-and-use-it-in-a-ci-process.md | 2 +- _docs/example-catalog/git-checkout-custom.md | 2 +- _docs/example-catalog/git-checkout.md | 3 +-- _docs/example-catalog/gitops-secrets.md | 2 +- _docs/example-catalog/golang.md | 2 +- _docs/example-catalog/golang/golang-hello-world.md | 2 +- _docs/example-catalog/golang/goreleaser.md | 2 +- _docs/example-catalog/helm.md | 2 +- _docs/example-catalog/import-data-to-mongodb.md | 2 +- _docs/example-catalog/integration-tests-with-mongo.md | 2 +- _docs/example-catalog/integration-tests-with-mysql.md | 2 +- _docs/example-catalog/integration-tests-with-postgres.md | 2 +- _docs/example-catalog/integration-tests-with-redis.md | 2 +- _docs/example-catalog/java.md | 2 +- _docs/example-catalog/java/gradle.md | 2 +- _docs/example-catalog/java/publish-jar.md | 2 +- _docs/example-catalog/java/spring-boot-2.md | 2 +- _docs/example-catalog/launch-composition.md | 2 +- ...fining-a-service-environment-variables-using-a-file.md | 2 +- _docs/example-catalog/mobile.md | 2 +- _docs/example-catalog/mobile/android.md | 2 +- _docs/example-catalog/nodejs-angular2-mongodb.md | 2 +- _docs/example-catalog/nodejs.md | 2 +- _docs/example-catalog/nodejs/lets-chat.md | 2 +- _docs/example-catalog/nodejs/react.md | 2 +- _docs/example-catalog/nodejs/voting-app.md | 2 +- _docs/example-catalog/nomad.md | 2 +- _docs/example-catalog/non-git-checkout.md | 2 +- _docs/example-catalog/packer-gcloud.md | 2 +- _docs/example-catalog/php.md | 2 +- .../populate-a-database-with-existing-data.md | 2 +- _docs/example-catalog/pulumi.md | 2 +- _docs/example-catalog/python.md | 2 +- _docs/example-catalog/python/django.md | 2 +- _docs/example-catalog/python/voting-app.md | 2 +- _docs/example-catalog/ruby.md | 2 +- _docs/example-catalog/run-integration-tests.md | 2 +- _docs/example-catalog/run-unit-tests.md | 2 +- _docs/example-catalog/rust.md | 2 +- _docs/example-catalog/scala.md | 2 +- _docs/example-catalog/scala/scala-hello-world.md | 2 +- .../secure-a-docker-container-using-http-basic-auth.md | 2 +- _docs/example-catalog/sending-the-notification-to-jira.md | 2 +- .../example-catalog/sending-the-notification-to-slack.md | 2 +- _docs/example-catalog/shared-volumes-between-builds.md | 2 +- ...f-service-from-composition-step-for-other-yml-steps.md | 2 +- _docs/example-catalog/spring-boot-kafka-zookeeper.md | 2 +- _docs/example-catalog/terraform.md | 2 +- _docs/example-catalog/transferring-php-ftp.md | 2 +- .../trigger-a-k8s-deployment-from-docker-registry.md | 2 +- _docs/example-catalog/uploading-or-downloading-from-gs.md | 2 +- .../use-kubectl-as-part-of-freestyle-step.md | 4 ++-- _docs/example-catalog/vault-secrets-in-the-pipeline.md | 2 +- _docs/example-catalog/web-terminal.md | 2 +- 79 files changed, 84 insertions(+), 87 deletions(-) diff --git a/_data/nav.yml b/_data/nav.yml index ee41fe36..222c9ac3 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -197,18 +197,18 @@ - title: "Example catalog" - url: "/examples" + url: "/example-catalog/examples" pages: - title: "Git" sub-pages: - title: Checking out Git repositories url: "/git-checkout" - title: Custom Git commmands - url: "/git-checkout-custom" + url: "/example-catalog/git-checkout-custom" - title: Non-Git checkouts - url: "/non-git-checkout" + url: "example-catalog/non-git-checkout" - title: Use Git Hash in CI - url: "/get-short-sha-id-and-use-it-in-a-ci-process" + url: "example-catalog/get-short-sha-id-and-use-it-in-a-ci-process" - title: "Image builds" sub-pages: - title: Build an Image with the Dockerfile in Root Directory diff --git a/_docs/example-catalog/amazon-ecs.md b/_docs/example-catalog/amazon-ecs.md index b4bdc8bd..a095ab40 100644 --- a/_docs/example-catalog/amazon-ecs.md +++ b/_docs/example-catalog/amazon-ecs.md @@ -1,8 +1,7 @@ --- title: "Amazon ECS/Fargate" description: "How to use Codefresh to deploy Docker containers to ECS/Fargate" -group: yaml-examples -sub_group: examples +group: example-catalog redirect_from: - /docs/amazon-ecs/ - /docs/deploy-your-containers/ diff --git a/_docs/example-catalog/build-an-image-from-a-different-git-repository.md b/_docs/example-catalog/build-an-image-from-a-different-git-repository.md index 736b030c..ef701492 100644 --- a/_docs/example-catalog/build-an-image-from-a-different-git-repository.md +++ b/_docs/example-catalog/build-an-image-from-a-different-git-repository.md @@ -1,8 +1,8 @@ --- title: "Build an Image from a Different Git Repository" description: "Build microservices from other repositories" -group: yaml-examples -sub_group: examples +group: example-catalog +sub_group: redirect_from: - /docs/build-an-image-from-a-different-git-repository/ toc: true diff --git a/_docs/example-catalog/build-an-image-specify-dockerfile-location.md b/_docs/example-catalog/build-an-image-specify-dockerfile-location.md index d8126780..21d3ea57 100644 --- a/_docs/example-catalog/build-an-image-specify-dockerfile-location.md +++ b/_docs/example-catalog/build-an-image-specify-dockerfile-location.md @@ -1,7 +1,7 @@ --- title: "Build an Image - Specify Dockerfile Location" description: "How to choose a Dockerfile to build with Codefresh pipelines" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/build-an-image-specify-dockerfile-location/ diff --git a/_docs/example-catalog/build-an-image-with-build-arguments.md b/_docs/example-catalog/build-an-image-with-build-arguments.md index d198733a..be255d28 100644 --- a/_docs/example-catalog/build-an-image-with-build-arguments.md +++ b/_docs/example-catalog/build-an-image-with-build-arguments.md @@ -1,8 +1,7 @@ --- title: "Build an Image with Build Arguments" description: "Use docker argument in Codefresh pipelines" -group: yaml-examples -sub_group: examples +group: example-catalog redirect_from: - /docs/build-an-image-with-build-arguments/ toc: true diff --git a/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md b/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md index 65565d21..920d6879 100644 --- a/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md +++ b/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md @@ -1,7 +1,7 @@ --- title: "Build an Image with the Dockerfile in Root Directory" description: "Get started quickly with building Docker images" -group: yaml-examples +group: example-catalog sub_group: examples permalink: /:collection/yaml-examples/examples/build-an-image-dockerfile-in-root-directory/ redirect_from: diff --git a/_docs/example-catalog/build-and-push-an-image.md b/_docs/example-catalog/build-and-push-an-image.md index 5c978e80..c0c2b910 100644 --- a/_docs/example-catalog/build-and-push-an-image.md +++ b/_docs/example-catalog/build-and-push-an-image.md @@ -1,7 +1,7 @@ --- title: "Build and Push an Image" description: "How to build Docker images and push them to registries with Codefresh" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/build-and-push-an-image/ diff --git a/_docs/example-catalog/call-child-pipelines.md b/_docs/example-catalog/call-child-pipelines.md index f672849a..f7f8d82b 100644 --- a/_docs/example-catalog/call-child-pipelines.md +++ b/_docs/example-catalog/call-child-pipelines.md @@ -1,7 +1,7 @@ --- title: "Calling a CD pipeline from a CI pipeline" description: "Learn how to call children pipelines from a parent pipeline" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/cc.md b/_docs/example-catalog/cc.md index 3a94ff95..c23c08fc 100644 --- a/_docs/example-catalog/cc.md +++ b/_docs/example-catalog/cc.md @@ -1,7 +1,7 @@ --- title: "C/C++" description: "How to build C/C++ applications with Codefresh CI/CD pipelines" -group: learn-by-example +group: example-catalog toc: true --- This section contains Codefresh examples based on C and C++. diff --git a/_docs/example-catalog/cc/c-make.md b/_docs/example-catalog/cc/c-make.md index 8dd0cc59..5d05f7e7 100644 --- a/_docs/example-catalog/cc/c-make.md +++ b/_docs/example-catalog/cc/c-make.md @@ -1,7 +1,7 @@ --- title: "Compile and test a C application" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog sub_group: cc toc: true --- diff --git a/_docs/example-catalog/cc/cpp-cmake.md b/_docs/example-catalog/cc/cpp-cmake.md index 4af30731..af272009 100644 --- a/_docs/example-catalog/cc/cpp-cmake.md +++ b/_docs/example-catalog/cc/cpp-cmake.md @@ -1,7 +1,7 @@ --- title: "Compile and test a C++ application" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog sub_group: cc toc: true --- diff --git a/_docs/example-catalog/codacy-testing.md b/_docs/example-catalog/codacy-testing.md index bda8c5e5..f8463d04 100644 --- a/_docs/example-catalog/codacy-testing.md +++ b/_docs/example-catalog/codacy-testing.md @@ -1,7 +1,7 @@ --- title: "Codacy Coverage Reports" description: "How to forward coverage reports to Codacy" -group: yaml-examples +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/codecov-testing.md b/_docs/example-catalog/codecov-testing.md index a0855bd9..1873be20 100644 --- a/_docs/example-catalog/codecov-testing.md +++ b/_docs/example-catalog/codecov-testing.md @@ -1,7 +1,7 @@ --- title: "Codecov Coverage Reports" description: "How to forward coverage reports to Codecov" -group: yaml-examples +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/coveralls-testing.md b/_docs/example-catalog/coveralls-testing.md index bd0b3f30..9a205601 100644 --- a/_docs/example-catalog/coveralls-testing.md +++ b/_docs/example-catalog/coveralls-testing.md @@ -1,7 +1,7 @@ --- title: "Coveralls Coverage Reports" description: "How to forward coverage reports to Coveralls" -group: yaml-examples +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/decryption-with-mozilla-sops.md b/_docs/example-catalog/decryption-with-mozilla-sops.md index 495e1785..112a6547 100644 --- a/_docs/example-catalog/decryption-with-mozilla-sops.md +++ b/_docs/example-catalog/decryption-with-mozilla-sops.md @@ -1,7 +1,7 @@ --- title: "Decryption with Mozilla SOPS" description: "Store secrets in your repository and decrypt them using Mozilla SOPS" -group: yaml-examples +group: example-catalogog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/deploy-to-heroku.md b/_docs/example-catalog/deploy-to-heroku.md index d724a90f..bf1e600d 100644 --- a/_docs/example-catalog/deploy-to-heroku.md +++ b/_docs/example-catalog/deploy-to-heroku.md @@ -1,7 +1,7 @@ --- title: "Deploy to Heroku" description: "Deploying your application or image to Heroku" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/deploy-to-tomcat-via-scp.md b/_docs/example-catalog/deploy-to-tomcat-via-scp.md index 320d0e5b..de240d38 100644 --- a/_docs/example-catalog/deploy-to-tomcat-via-scp.md +++ b/_docs/example-catalog/deploy-to-tomcat-via-scp.md @@ -1,7 +1,7 @@ --- title: "Deploy to a VM via SCP" description: "Deploying your application to Tomcat using SCP" -group: yaml-examples +group: example-catalogog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/deploy-with-kustomize.md b/_docs/example-catalog/deploy-with-kustomize.md index 8b5dac97..bcc77118 100644 --- a/_docs/example-catalog/deploy-with-kustomize.md +++ b/_docs/example-catalog/deploy-with-kustomize.md @@ -1,7 +1,7 @@ --- title: "Deploy to Kubernetes with Kustomize" description: "Deploy your services to Kubernetes using Kustomize" -group: yaml-examples +group: example-catalogog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/docker-swarm.md b/_docs/example-catalog/docker-swarm.md index 3075f406..ff9e29ff 100644 --- a/_docs/example-catalog/docker-swarm.md +++ b/_docs/example-catalog/docker-swarm.md @@ -1,7 +1,7 @@ --- title: "Docker SWARM" description: "How to deploy to Docker Swarm with Codefresh" -group: yaml-examples +group: example-catalogog sub_group: examples redirect_from: - /docs/docker-swarm/ diff --git a/_docs/example-catalog/dotnet.md b/_docs/example-catalog/dotnet.md index 9862e0c6..09496bd5 100644 --- a/_docs/example-catalog/dotnet.md +++ b/_docs/example-catalog/dotnet.md @@ -1,7 +1,7 @@ --- title: "C# on .NET Core" description: "How to build a C# project in Codefresh" -group: learn-by-example +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/elastic-beanstalk.md b/_docs/example-catalog/elastic-beanstalk.md index 3df5a510..8a02e011 100644 --- a/_docs/example-catalog/elastic-beanstalk.md +++ b/_docs/example-catalog/elastic-beanstalk.md @@ -1,7 +1,7 @@ --- title: "Elastic Beanstalk" description: "" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/elastic-beanstalk/ diff --git a/_docs/example-catalog/examples.md b/_docs/example-catalog/examples.md index d1d968ca..bfd48b3d 100644 --- a/_docs/example-catalog/examples.md +++ b/_docs/example-catalog/examples.md @@ -1,7 +1,7 @@ --- title: "CI/CD pipeline examples" description: "A collection of examples for Codefresh pipelines" -group: yaml-examples +group: example-catalog redirect_from: - /docs/examples-v01/ - examples.html diff --git a/_docs/example-catalog/fan-in-fan-out.md b/_docs/example-catalog/fan-in-fan-out.md index 59d9775d..89532841 100644 --- a/_docs/example-catalog/fan-in-fan-out.md +++ b/_docs/example-catalog/fan-in-fan-out.md @@ -1,7 +1,7 @@ --- title: "Fan-out-fan-in Pipeline" description: "Use parallel mode to fan-in and fan-out your step dependencies" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/general.md b/_docs/example-catalog/general.md index 20d5bd50..3cec98bc 100644 --- a/_docs/example-catalog/general.md +++ b/_docs/example-catalog/general.md @@ -1,7 +1,7 @@ --- title: "General" description: "" -group: learn-by-example +group: example-catalog redirect_from: - /docs/learn-by-example/general/ toc: true diff --git a/_docs/example-catalog/general/selenium-test.md b/_docs/example-catalog/general/selenium-test.md index be3d80b2..424e22db 100644 --- a/_docs/example-catalog/general/selenium-test.md +++ b/_docs/example-catalog/general/selenium-test.md @@ -2,7 +2,7 @@ title: "Selenium test" description: "" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: general redirect_from: - /docs/general/selenium-test/ diff --git a/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md b/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md index bc96d9f6..a4d70d59 100644 --- a/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md +++ b/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md @@ -1,7 +1,7 @@ --- title: "Get Short SHA ID and Use it in a CI Process" description: "" -group: yaml-examples +group: example-catalogog sub_group: examples redirect_from: - /docs/how-to-guides/ diff --git a/_docs/example-catalog/git-checkout-custom.md b/_docs/example-catalog/git-checkout-custom.md index c7e01e10..6323bd6d 100644 --- a/_docs/example-catalog/git-checkout-custom.md +++ b/_docs/example-catalog/git-checkout-custom.md @@ -1,7 +1,7 @@ --- title: "Using Custom Git commands" description: "Clone manually git repositories" -group: yaml-examples +group: example-catalogogog sub_group: git redirect_from: - /docs/git-clone-private-repository-using-freestyle-step/ diff --git a/_docs/example-catalog/git-checkout.md b/_docs/example-catalog/git-checkout.md index e4de0cff..4b26e7bd 100644 --- a/_docs/example-catalog/git-checkout.md +++ b/_docs/example-catalog/git-checkout.md @@ -1,8 +1,7 @@ --- title: "Checking out Git repositories" description: "Using the Codefresh native GIT integration" -group: yaml-examples -sub_group: examples +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/gitops-secrets.md b/_docs/example-catalog/gitops-secrets.md index 84c05726..97853fe5 100644 --- a/_docs/example-catalog/gitops-secrets.md +++ b/_docs/example-catalog/gitops-secrets.md @@ -1,7 +1,7 @@ --- title: "Using secrets with GitOps" description: "Store secrets in Git with Bitnami sealed secrets" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/golang.md b/_docs/example-catalog/golang.md index 71a0f869..3f9798e6 100644 --- a/_docs/example-catalog/golang.md +++ b/_docs/example-catalog/golang.md @@ -1,7 +1,7 @@ --- title: "Go" description: "How to build Golang applications with Codefresh CI/CD pipelines" -group: learn-by-example +group: example-catalog redirect_from: - /docs/go/ - /docs/golang/ diff --git a/_docs/example-catalog/golang/golang-hello-world.md b/_docs/example-catalog/golang/golang-hello-world.md index 665c43ab..bf639405 100644 --- a/_docs/example-catalog/golang/golang-hello-world.md +++ b/_docs/example-catalog/golang/golang-hello-world.md @@ -1,7 +1,7 @@ --- title: "Create a Docker image for GO" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog sub_group: golang redirect_from: - /docs/go/cf-example-golang-hello-world/ diff --git a/_docs/example-catalog/golang/goreleaser.md b/_docs/example-catalog/golang/goreleaser.md index aa6e955d..56300fbc 100644 --- a/_docs/example-catalog/golang/goreleaser.md +++ b/_docs/example-catalog/golang/goreleaser.md @@ -1,7 +1,7 @@ --- title: "Compile and release a Go application" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog sub_group: golang toc: true --- diff --git a/_docs/example-catalog/helm.md b/_docs/example-catalog/helm.md index ba32dae4..0ccfa6bc 100644 --- a/_docs/example-catalog/helm.md +++ b/_docs/example-catalog/helm.md @@ -1,7 +1,7 @@ --- title: "Deploy with Helm" description: "Use Helm in a Codefresh pipeline" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/import-data-to-mongodb.md b/_docs/example-catalog/import-data-to-mongodb.md index 96c826ae..263a5111 100644 --- a/_docs/example-catalog/import-data-to-mongodb.md +++ b/_docs/example-catalog/import-data-to-mongodb.md @@ -2,7 +2,7 @@ title: "Import data to MongoDB" description: "" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/import-data-to-mongodb-in-composition/ diff --git a/_docs/example-catalog/integration-tests-with-mongo.md b/_docs/example-catalog/integration-tests-with-mongo.md index e11fd4eb..5bd5aef1 100644 --- a/_docs/example-catalog/integration-tests-with-mongo.md +++ b/_docs/example-catalog/integration-tests-with-mongo.md @@ -1,7 +1,7 @@ --- title: "Integration Tests with Mongo" description: "Launching a MongoDB service container" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/nodejsmongo/ diff --git a/_docs/example-catalog/integration-tests-with-mysql.md b/_docs/example-catalog/integration-tests-with-mysql.md index e08ee064..8d32674a 100644 --- a/_docs/example-catalog/integration-tests-with-mysql.md +++ b/_docs/example-catalog/integration-tests-with-mysql.md @@ -1,7 +1,7 @@ --- title: "Integration Tests with MySQL" description: "Launching a MySQL service container" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/nodejsmysql/ diff --git a/_docs/example-catalog/integration-tests-with-postgres.md b/_docs/example-catalog/integration-tests-with-postgres.md index 43e419f8..297de364 100644 --- a/_docs/example-catalog/integration-tests-with-postgres.md +++ b/_docs/example-catalog/integration-tests-with-postgres.md @@ -1,7 +1,7 @@ --- title: "Integration Tests with Postgres" description: "Launching a PostgreSQL service container" -group: yaml-examples +group: example-catalogog sub_group: examples redirect_from: - /docs/unit-tests-with-postgres/ diff --git a/_docs/example-catalog/integration-tests-with-redis.md b/_docs/example-catalog/integration-tests-with-redis.md index 45d21884..b8deeba6 100644 --- a/_docs/example-catalog/integration-tests-with-redis.md +++ b/_docs/example-catalog/integration-tests-with-redis.md @@ -1,7 +1,7 @@ --- title: "Integration Tests with Redis" description: "Launching a Redis service container" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/python-redis/ diff --git a/_docs/example-catalog/java.md b/_docs/example-catalog/java.md index 2229280b..c28cd55c 100644 --- a/_docs/example-catalog/java.md +++ b/_docs/example-catalog/java.md @@ -1,7 +1,7 @@ --- title: "Java" description: "" -group: learn-by-example +group: example-catalog redirect_from: - /docs/java/ toc: true diff --git a/_docs/example-catalog/java/gradle.md b/_docs/example-catalog/java/gradle.md index 76697af5..ea0c3daf 100644 --- a/_docs/example-catalog/java/gradle.md +++ b/_docs/example-catalog/java/gradle.md @@ -2,7 +2,7 @@ title: "Java Example with Gradle and Docker" description: "Create Docker images for Spring/Gradle" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: java redirect_from: - /docs/java/gradle/ diff --git a/_docs/example-catalog/java/publish-jar.md b/_docs/example-catalog/java/publish-jar.md index c5f8929a..4a982fe9 100644 --- a/_docs/example-catalog/java/publish-jar.md +++ b/_docs/example-catalog/java/publish-jar.md @@ -2,7 +2,7 @@ title: "Publish Jar" description: "How to upload a JAR file to Nexus or artifactory" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: java toc: true --- diff --git a/_docs/example-catalog/java/spring-boot-2.md b/_docs/example-catalog/java/spring-boot-2.md index 5078714c..a692d920 100644 --- a/_docs/example-catalog/java/spring-boot-2.md +++ b/_docs/example-catalog/java/spring-boot-2.md @@ -2,7 +2,7 @@ title: "Spring Boot 2/Maven" description: "Create Docker images for Spring/Maven" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: java redirect_from: - /docs/spring-boot-2/ diff --git a/_docs/example-catalog/launch-composition.md b/_docs/example-catalog/launch-composition.md index 83a616f5..913ff22b 100644 --- a/_docs/example-catalog/launch-composition.md +++ b/_docs/example-catalog/launch-composition.md @@ -1,7 +1,7 @@ --- title: "Launch Composition" description: "Create a dynamic environment to preview your feature" -group: yaml-examples +group: example-catalogogog sub_group: examples redirect_from: - /docs/launch-composition-1/ diff --git a/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md b/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md index af5f36f9..df00f4c0 100644 --- a/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md +++ b/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md @@ -1,7 +1,7 @@ --- title: "Launching a composition and defining a service environment variable using a file" description: "" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/launching-a-composition-and-passing-a-service-environment-variable-using-a-file/ diff --git a/_docs/example-catalog/mobile.md b/_docs/example-catalog/mobile.md index 70f7a777..d05b24b9 100644 --- a/_docs/example-catalog/mobile.md +++ b/_docs/example-catalog/mobile.md @@ -1,7 +1,7 @@ --- title: "Mobile Apps" description: "How to build Mobile applications with Codefresh CI/CD pipelines" -group: learn-by-example +group: example-catalog toc: true --- This section contains Codefresh examples for Mobile application. diff --git a/_docs/example-catalog/mobile/android.md b/_docs/example-catalog/mobile/android.md index 6d0b01e9..2985c31d 100644 --- a/_docs/example-catalog/mobile/android.md +++ b/_docs/example-catalog/mobile/android.md @@ -1,7 +1,7 @@ --- title: "Compile and package an Android application" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog sub_group: mobile toc: true --- diff --git a/_docs/example-catalog/nodejs-angular2-mongodb.md b/_docs/example-catalog/nodejs-angular2-mongodb.md index aa5b679a..7459b31d 100644 --- a/_docs/example-catalog/nodejs-angular2-mongodb.md +++ b/_docs/example-catalog/nodejs-angular2-mongodb.md @@ -1,7 +1,7 @@ --- title: "NodeJS + Angular2 + MongoDB" description: "" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/nodejs-angular2-mongodb/ diff --git a/_docs/example-catalog/nodejs.md b/_docs/example-catalog/nodejs.md index 0f5cc4fe..f057d787 100644 --- a/_docs/example-catalog/nodejs.md +++ b/_docs/example-catalog/nodejs.md @@ -1,7 +1,7 @@ --- title: "Node.js" description: "" -group: learn-by-example +group: example-catalog redirect_from: - /docs/nodejs/ toc: true diff --git a/_docs/example-catalog/nodejs/lets-chat.md b/_docs/example-catalog/nodejs/lets-chat.md index 649f5cf3..9a5dea49 100644 --- a/_docs/example-catalog/nodejs/lets-chat.md +++ b/_docs/example-catalog/nodejs/lets-chat.md @@ -1,7 +1,7 @@ --- title: "Let's Chat example" description: "Create Docker images for Node/Express.js applications" -group: learn-by-example +group: example-catalog sub_group: nodejs redirect_from: - /docs/lets-chat/ diff --git a/_docs/example-catalog/nodejs/react.md b/_docs/example-catalog/nodejs/react.md index e79b7a5b..fd9d0d1f 100644 --- a/_docs/example-catalog/nodejs/react.md +++ b/_docs/example-catalog/nodejs/react.md @@ -1,7 +1,7 @@ --- title: "React example with Yarn" description: "Create Docker images for React applications" -group: learn-by-example +group: example-catalog sub_group: nodejs toc: true --- diff --git a/_docs/example-catalog/nodejs/voting-app.md b/_docs/example-catalog/nodejs/voting-app.md index 48c5da61..32b186e7 100644 --- a/_docs/example-catalog/nodejs/voting-app.md +++ b/_docs/example-catalog/nodejs/voting-app.md @@ -2,7 +2,7 @@ title: "Voting app" description: "" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: nodejs redirect_from: - /docs/voting-app/ diff --git a/_docs/example-catalog/nomad.md b/_docs/example-catalog/nomad.md index fbe6821a..efc1d391 100644 --- a/_docs/example-catalog/nomad.md +++ b/_docs/example-catalog/nomad.md @@ -1,7 +1,7 @@ --- title: "Deploy to Nomad" description: "Deploy Docker images to a Nomad cluster with Codefresh" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/non-git-checkout.md b/_docs/example-catalog/non-git-checkout.md index dec584ef..bf148d8c 100644 --- a/_docs/example-catalog/non-git-checkout.md +++ b/_docs/example-catalog/non-git-checkout.md @@ -1,7 +1,7 @@ --- title: "Checking out from other Source Control systems" description: "Work with non-git repositories" -group: yaml-examples +group: example-catalogog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/packer-gcloud.md b/_docs/example-catalog/packer-gcloud.md index 5e543064..2165a045 100644 --- a/_docs/example-catalog/packer-gcloud.md +++ b/_docs/example-catalog/packer-gcloud.md @@ -1,7 +1,7 @@ --- title: "Deploy to a Virtual Machine" description: "Deploy to Google Cloud in a Codefresh pipeline with Packer" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/php.md b/_docs/example-catalog/php.md index 219b7224..9e16158c 100644 --- a/_docs/example-catalog/php.md +++ b/_docs/example-catalog/php.md @@ -1,7 +1,7 @@ --- title: "Create a Docker image for Php" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/populate-a-database-with-existing-data.md b/_docs/example-catalog/populate-a-database-with-existing-data.md index ae477c0a..b775c39c 100644 --- a/_docs/example-catalog/populate-a-database-with-existing-data.md +++ b/_docs/example-catalog/populate-a-database-with-existing-data.md @@ -1,7 +1,7 @@ --- title: "Populate a database with existing data" description: "Preloading test data before integration tests" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/populate-a-database-with-existing-data-copied/ diff --git a/_docs/example-catalog/pulumi.md b/_docs/example-catalog/pulumi.md index ef90bb89..b125f5a6 100644 --- a/_docs/example-catalog/pulumi.md +++ b/_docs/example-catalog/pulumi.md @@ -1,7 +1,7 @@ --- title: "Deploy with Pulumi" description: "Use Pulumi in a Codefresh pipeline with Docker" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/python.md b/_docs/example-catalog/python.md index 76f5c347..d80cb991 100644 --- a/_docs/example-catalog/python.md +++ b/_docs/example-catalog/python.md @@ -1,7 +1,7 @@ --- title: "Python" description: "" -group: learn-by-example +group: example-catalog redirect_from: - /docs/python/ toc: true diff --git a/_docs/example-catalog/python/django.md b/_docs/example-catalog/python/django.md index 92ba1375..063bc7a4 100644 --- a/_docs/example-catalog/python/django.md +++ b/_docs/example-catalog/python/django.md @@ -2,7 +2,7 @@ title: "Python Django example" description: "Create Docker images for Python applications" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: python redirect_from: - /docs/django/ diff --git a/_docs/example-catalog/python/voting-app.md b/_docs/example-catalog/python/voting-app.md index bce847bc..fea85e68 100644 --- a/_docs/example-catalog/python/voting-app.md +++ b/_docs/example-catalog/python/voting-app.md @@ -2,7 +2,7 @@ title: "Voting app" description: "" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: python redirect_from: - /docs/voting-app-1/ diff --git a/_docs/example-catalog/ruby.md b/_docs/example-catalog/ruby.md index cfc42bc7..7d717c83 100644 --- a/_docs/example-catalog/ruby.md +++ b/_docs/example-catalog/ruby.md @@ -1,7 +1,7 @@ --- title: "Ruby" description: "How to build a Ruby On Rails project in Codefresh" -group: learn-by-example +group: example-catalog toc: true --- Ruby on Rails is a very popular development framework that combines ease of use and a great amount of programming languages. In Codefresh, ROR projects behave like any other web application. You can easily build them, run [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) and launch them on [demo environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/). diff --git a/_docs/example-catalog/run-integration-tests.md b/_docs/example-catalog/run-integration-tests.md index 0b92e9b0..9d20ea68 100644 --- a/_docs/example-catalog/run-integration-tests.md +++ b/_docs/example-catalog/run-integration-tests.md @@ -1,7 +1,7 @@ --- title: "Integration Tests Example" description: "Launching separate App and test containers" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/run-integration-tests/ diff --git a/_docs/example-catalog/run-unit-tests.md b/_docs/example-catalog/run-unit-tests.md index 9c4c7a79..e4117866 100644 --- a/_docs/example-catalog/run-unit-tests.md +++ b/_docs/example-catalog/run-unit-tests.md @@ -1,7 +1,7 @@ --- title: "Run Unit Tests" description: "Running unit tests in Codefresh pipelines" -group: yaml-examples +group: example-catalogog sub_group: examples redirect_from: - /docs/run-unit-tests/ diff --git a/_docs/example-catalog/rust.md b/_docs/example-catalog/rust.md index 08f58445..ad3cea20 100644 --- a/_docs/example-catalog/rust.md +++ b/_docs/example-catalog/rust.md @@ -1,7 +1,7 @@ --- title: "Compile and test a Rust application" description: "Using Codefresh pipelines" -group: learn-by-example +group: example-catalog toc: true --- diff --git a/_docs/example-catalog/scala.md b/_docs/example-catalog/scala.md index 5a0991f4..7415259d 100644 --- a/_docs/example-catalog/scala.md +++ b/_docs/example-catalog/scala.md @@ -1,7 +1,7 @@ --- title: "Scala" description: "" -group: learn-by-example +group: example-catalog redirect_from: - /docs/scala/ toc: true diff --git a/_docs/example-catalog/scala/scala-hello-world.md b/_docs/example-catalog/scala/scala-hello-world.md index 629da23d..122febc1 100644 --- a/_docs/example-catalog/scala/scala-hello-world.md +++ b/_docs/example-catalog/scala/scala-hello-world.md @@ -2,7 +2,7 @@ title: "Scala: Hello World" description: "Use Scala and Codefresh to clone, package, and build a Docker image" excerpt: "" -group: learn-by-example +group: example-catalog sub_group: scala redirect_from: - /docs/scala-hello-world/ diff --git a/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md b/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md index 301fbe8d..afa61199 100644 --- a/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md +++ b/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md @@ -1,7 +1,7 @@ --- title: "Secure a Docker Container Using HTTP Basic Auth" description: "" -group: yaml-examples +group: example-catalogog sub_group: examples redirect_from: - /docs/securing-docker-container-with-http-basic-auth/ diff --git a/_docs/example-catalog/sending-the-notification-to-jira.md b/_docs/example-catalog/sending-the-notification-to-jira.md index f43e7b91..a1be2f9e 100644 --- a/_docs/example-catalog/sending-the-notification-to-jira.md +++ b/_docs/example-catalog/sending-the-notification-to-jira.md @@ -1,7 +1,7 @@ --- title: "Sending the notification to Jira" description: "" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/sending-the-notification-to-slack.md b/_docs/example-catalog/sending-the-notification-to-slack.md index 63e1254b..352cd633 100644 --- a/_docs/example-catalog/sending-the-notification-to-slack.md +++ b/_docs/example-catalog/sending-the-notification-to-slack.md @@ -1,7 +1,7 @@ --- title: "Sending a notification to Slack" description: "Connect your Codefresh pipelines to Slack" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/sending-the-notification-to-slack/ diff --git a/_docs/example-catalog/shared-volumes-between-builds.md b/_docs/example-catalog/shared-volumes-between-builds.md index 9658a27e..e63833df 100644 --- a/_docs/example-catalog/shared-volumes-between-builds.md +++ b/_docs/example-catalog/shared-volumes-between-builds.md @@ -1,7 +1,7 @@ --- title: "Sharing data between pipeline steps" description: "How to cache folders between steps and builds" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/shared-volumes-between-builds/ diff --git a/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md b/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md index 63e98467..50ca3507 100644 --- a/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md +++ b/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md @@ -1,7 +1,7 @@ --- title: "Shared volumes of service from composition step for other yml steps" description: "How to share data in compositions" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/shared-volumes-of-service-from-composition-step-for-other-yml-steps/ diff --git a/_docs/example-catalog/spring-boot-kafka-zookeeper.md b/_docs/example-catalog/spring-boot-kafka-zookeeper.md index 675a1a5e..fc48d462 100644 --- a/_docs/example-catalog/spring-boot-kafka-zookeeper.md +++ b/_docs/example-catalog/spring-boot-kafka-zookeeper.md @@ -1,7 +1,7 @@ --- title: "Spring Boot + Kafka + Zookeeper" description: "" -group: yaml-examples +group: example-catalogogog sub_group: examples redirect_from: - /docs/spring-boot-kafka-zookeeper/ diff --git a/_docs/example-catalog/terraform.md b/_docs/example-catalog/terraform.md index 40de1d73..b1642fbc 100644 --- a/_docs/example-catalog/terraform.md +++ b/_docs/example-catalog/terraform.md @@ -1,7 +1,7 @@ --- title: "Deploy with Terraform" description: "Use Terraform in a Codefresh pipeline with Docker" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/transferring-php-ftp.md b/_docs/example-catalog/transferring-php-ftp.md index 5b8d513f..3585193d 100644 --- a/_docs/example-catalog/transferring-php-ftp.md +++ b/_docs/example-catalog/transferring-php-ftp.md @@ -1,7 +1,7 @@ --- title: "Transferring Applications via FTP" description: "Deploying a Php Application to a VM using FTP" -group: yaml-examples +group: example-catalog sub_group: examples toc: true redirect_from: diff --git a/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md b/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md index 95f914eb..7d3d3654 100644 --- a/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md +++ b/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md @@ -1,7 +1,7 @@ --- title: "Trigger a Kubernetes Deployment from a Dockerhub Push Event" description: "Learn how to trigger a Kubernetes deployment when an image is updated" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/uploading-or-downloading-from-gs.md b/_docs/example-catalog/uploading-or-downloading-from-gs.md index a9b00bfd..ab05aa9a 100644 --- a/_docs/example-catalog/uploading-or-downloading-from-gs.md +++ b/_docs/example-catalog/uploading-or-downloading-from-gs.md @@ -1,7 +1,7 @@ --- title: "Uploading/Downloading Files to/from Google Storage" description: "Upload and download a jar from Google Storage from within a pipeline" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md b/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md index 4a09761d..d5c772c0 100644 --- a/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md +++ b/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md @@ -1,8 +1,8 @@ --- title: "Use kubectl as part of Freestyle step" description: "How to run manually kubectl in a Codefresh pipeline" -group: yaml-examples -sub_group: examples +group: example-catalog +sub_group: redirect_from: - /docs/use-kubectl-as-part-of-freestyle-step/ toc: true diff --git a/_docs/example-catalog/vault-secrets-in-the-pipeline.md b/_docs/example-catalog/vault-secrets-in-the-pipeline.md index 7344ce06..39a38cf0 100644 --- a/_docs/example-catalog/vault-secrets-in-the-pipeline.md +++ b/_docs/example-catalog/vault-secrets-in-the-pipeline.md @@ -1,7 +1,7 @@ --- title: "Vault Secrets in the Pipeline" description: "Accessing and Referring to Vault Secrets in the Pipeline" -group: yaml-examples +group: example-catalog sub_group: examples toc: true --- diff --git a/_docs/example-catalog/web-terminal.md b/_docs/example-catalog/web-terminal.md index d99308da..b2db9321 100644 --- a/_docs/example-catalog/web-terminal.md +++ b/_docs/example-catalog/web-terminal.md @@ -1,7 +1,7 @@ --- title: "Web terminal" description: "" -group: yaml-examples +group: example-catalog sub_group: examples redirect_from: - /docs/web-terminal/ From 1e033d7d253cf3e25c30d06cb3ae6a5bc43d2f73 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 15:44:29 +0200 Subject: [PATCH 04/17] Update example-catalog structure --- _data/nav.yml | 98 ++++++++----------- .../{ => cd-examples}/amazon-ecs.md | 0 .../{ => cd-examples}/deploy-to-heroku.md | 0 .../deploy-to-tomcat-via-scp.md | 0 .../deploy-with-kustomize.md | 0 .../{ => cd-examples}/docker-swarm.md | 0 .../{ => cd-examples}/elastic-beanstalk.md | 0 .../example-catalog/{ => cd-examples}/helm.md | 0 .../import-data-to-mongodb.md | 0 .../nodejs-angular2-mongodb.md | 0 .../{ => cd-examples}/nomad.md | 0 .../{ => cd-examples}/packer-gcloud.md | 0 .../{ => cd-examples}/pulumi.md | 0 ...-docker-container-using-http-basic-auth.md | 0 .../spring-boot-kafka-zookeeper.md | 0 .../{ => cd-examples}/terraform.md | 0 .../{ => cd-examples}/transferring-php-ftp.md | 0 ...r-a-k8s-deployment-from-docker-registry.md | 0 .../use-kubectl-as-part-of-freestyle-step.md | 0 .../{ => cd-examples}/web-terminal.md | 0 .../{mobile => ci-examples}/android.md | 0 ...n-image-from-a-different-git-repository.md | 0 ...ld-an-image-specify-dockerfile-location.md | 0 .../build-an-image-with-build-arguments.md | 0 ...e-with-the-dockerfile-in-root-directory.md | 0 .../build-and-push-an-image.md | 0 .../{cc => ci-examples}/c-make.md | 0 .../{ => ci-examples}/call-child-pipelines.md | 0 _docs/example-catalog/{ => ci-examples}/cc.md | 0 .../{ => ci-examples}/codacy-testing.md | 0 .../{ => ci-examples}/codecov-testing.md | 0 .../{ => ci-examples}/coveralls-testing.md | 0 .../{cc => ci-examples}/cpp-cmake.md | 0 .../decryption-with-mozilla-sops.md | 0 .../{python => ci-examples}/django.md | 0 .../{ => ci-examples}/dotnet.md | 0 .../{ => ci-examples}/examples.md | 0 .../{ => ci-examples}/fan-in-fan-out.md | 0 .../{ => ci-examples}/general.md | 0 ...short-sha-id-and-use-it-in-a-ci-process.md | 0 .../{ => ci-examples}/git-checkout-custom.md | 0 .../{ => ci-examples}/git-checkout.md | 0 .../{ => ci-examples}/gitops-secrets.md | 0 .../golang-hello-world.md | 0 .../{ => ci-examples}/golang.md | 0 .../{golang => ci-examples}/goreleaser.md | 0 .../{java => ci-examples}/gradle.md | 0 .../integration-tests-with-mongo.md | 0 .../integration-tests-with-mysql.md | 0 .../integration-tests-with-postgres.md | 0 .../integration-tests-with-redis.md | 0 .../example-catalog/{ => ci-examples}/java.md | 0 .../{ => ci-examples}/launch-composition.md | 0 ...vice-environment-variables-using-a-file.md | 0 .../{nodejs => ci-examples}/lets-chat.md | 0 .../{ => ci-examples}/mobile.md | 0 .../{ => ci-examples}/nodejs.md | 0 .../{ => ci-examples}/non-git-checkout.md | 0 .../example-catalog/{ => ci-examples}/php.md | 0 .../populate-a-database-with-existing-data.md | 0 .../{java => ci-examples}/publish-jar.md | 0 .../{ => ci-examples}/python.md | 0 .../{nodejs => ci-examples}/react.md | 0 .../example-catalog/{ => ci-examples}/ruby.md | 0 .../run-integration-tests.md | 0 .../{ => ci-examples}/run-unit-tests.md | 0 .../example-catalog/{ => ci-examples}/rust.md | 0 .../scala-hello-world.md | 0 .../{ => ci-examples}/scala.md | 0 .../sending-the-notification-to-jira.md | 0 .../sending-the-notification-to-slack.md | 0 .../shared-volumes-between-builds.md | 0 ...om-composition-step-for-other-yml-steps.md | 0 .../{java => ci-examples}/spring-boot-2.md | 0 .../uploading-or-downloading-from-gs.md | 0 .../vault-secrets-in-the-pipeline.md | 0 .../{python => ci-examples}/voting-app.md | 0 .../example-catalog/general/selenium-test.md | 75 -------------- _docs/example-catalog/nodejs/voting-app.md | 88 ----------------- 79 files changed, 39 insertions(+), 222 deletions(-) rename _docs/example-catalog/{ => cd-examples}/amazon-ecs.md (100%) rename _docs/example-catalog/{ => cd-examples}/deploy-to-heroku.md (100%) rename _docs/example-catalog/{ => cd-examples}/deploy-to-tomcat-via-scp.md (100%) rename _docs/example-catalog/{ => cd-examples}/deploy-with-kustomize.md (100%) rename _docs/example-catalog/{ => cd-examples}/docker-swarm.md (100%) rename _docs/example-catalog/{ => cd-examples}/elastic-beanstalk.md (100%) rename _docs/example-catalog/{ => cd-examples}/helm.md (100%) rename _docs/example-catalog/{ => cd-examples}/import-data-to-mongodb.md (100%) rename _docs/example-catalog/{ => cd-examples}/nodejs-angular2-mongodb.md (100%) rename _docs/example-catalog/{ => cd-examples}/nomad.md (100%) rename _docs/example-catalog/{ => cd-examples}/packer-gcloud.md (100%) rename _docs/example-catalog/{ => cd-examples}/pulumi.md (100%) rename _docs/example-catalog/{ => cd-examples}/secure-a-docker-container-using-http-basic-auth.md (100%) rename _docs/example-catalog/{ => cd-examples}/spring-boot-kafka-zookeeper.md (100%) rename _docs/example-catalog/{ => cd-examples}/terraform.md (100%) rename _docs/example-catalog/{ => cd-examples}/transferring-php-ftp.md (100%) rename _docs/example-catalog/{ => cd-examples}/trigger-a-k8s-deployment-from-docker-registry.md (100%) rename _docs/example-catalog/{ => cd-examples}/use-kubectl-as-part-of-freestyle-step.md (100%) rename _docs/example-catalog/{ => cd-examples}/web-terminal.md (100%) rename _docs/example-catalog/{mobile => ci-examples}/android.md (100%) rename _docs/example-catalog/{ => ci-examples}/build-an-image-from-a-different-git-repository.md (100%) rename _docs/example-catalog/{ => ci-examples}/build-an-image-specify-dockerfile-location.md (100%) rename _docs/example-catalog/{ => ci-examples}/build-an-image-with-build-arguments.md (100%) rename _docs/example-catalog/{ => ci-examples}/build-an-image-with-the-dockerfile-in-root-directory.md (100%) rename _docs/example-catalog/{ => ci-examples}/build-and-push-an-image.md (100%) rename _docs/example-catalog/{cc => ci-examples}/c-make.md (100%) rename _docs/example-catalog/{ => ci-examples}/call-child-pipelines.md (100%) rename _docs/example-catalog/{ => ci-examples}/cc.md (100%) rename _docs/example-catalog/{ => ci-examples}/codacy-testing.md (100%) rename _docs/example-catalog/{ => ci-examples}/codecov-testing.md (100%) rename _docs/example-catalog/{ => ci-examples}/coveralls-testing.md (100%) rename _docs/example-catalog/{cc => ci-examples}/cpp-cmake.md (100%) rename _docs/example-catalog/{ => ci-examples}/decryption-with-mozilla-sops.md (100%) rename _docs/example-catalog/{python => ci-examples}/django.md (100%) rename _docs/example-catalog/{ => ci-examples}/dotnet.md (100%) rename _docs/example-catalog/{ => ci-examples}/examples.md (100%) rename _docs/example-catalog/{ => ci-examples}/fan-in-fan-out.md (100%) rename _docs/example-catalog/{ => ci-examples}/general.md (100%) rename _docs/example-catalog/{ => ci-examples}/get-short-sha-id-and-use-it-in-a-ci-process.md (100%) rename _docs/example-catalog/{ => ci-examples}/git-checkout-custom.md (100%) rename _docs/example-catalog/{ => ci-examples}/git-checkout.md (100%) rename _docs/example-catalog/{ => ci-examples}/gitops-secrets.md (100%) rename _docs/example-catalog/{golang => ci-examples}/golang-hello-world.md (100%) rename _docs/example-catalog/{ => ci-examples}/golang.md (100%) rename _docs/example-catalog/{golang => ci-examples}/goreleaser.md (100%) rename _docs/example-catalog/{java => ci-examples}/gradle.md (100%) rename _docs/example-catalog/{ => ci-examples}/integration-tests-with-mongo.md (100%) rename _docs/example-catalog/{ => ci-examples}/integration-tests-with-mysql.md (100%) rename _docs/example-catalog/{ => ci-examples}/integration-tests-with-postgres.md (100%) rename _docs/example-catalog/{ => ci-examples}/integration-tests-with-redis.md (100%) rename _docs/example-catalog/{ => ci-examples}/java.md (100%) rename _docs/example-catalog/{ => ci-examples}/launch-composition.md (100%) rename _docs/example-catalog/{ => ci-examples}/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md (100%) rename _docs/example-catalog/{nodejs => ci-examples}/lets-chat.md (100%) rename _docs/example-catalog/{ => ci-examples}/mobile.md (100%) rename _docs/example-catalog/{ => ci-examples}/nodejs.md (100%) rename _docs/example-catalog/{ => ci-examples}/non-git-checkout.md (100%) rename _docs/example-catalog/{ => ci-examples}/php.md (100%) rename _docs/example-catalog/{ => ci-examples}/populate-a-database-with-existing-data.md (100%) rename _docs/example-catalog/{java => ci-examples}/publish-jar.md (100%) rename _docs/example-catalog/{ => ci-examples}/python.md (100%) rename _docs/example-catalog/{nodejs => ci-examples}/react.md (100%) rename _docs/example-catalog/{ => ci-examples}/ruby.md (100%) rename _docs/example-catalog/{ => ci-examples}/run-integration-tests.md (100%) rename _docs/example-catalog/{ => ci-examples}/run-unit-tests.md (100%) rename _docs/example-catalog/{ => ci-examples}/rust.md (100%) rename _docs/example-catalog/{scala => ci-examples}/scala-hello-world.md (100%) rename _docs/example-catalog/{ => ci-examples}/scala.md (100%) rename _docs/example-catalog/{ => ci-examples}/sending-the-notification-to-jira.md (100%) rename _docs/example-catalog/{ => ci-examples}/sending-the-notification-to-slack.md (100%) rename _docs/example-catalog/{ => ci-examples}/shared-volumes-between-builds.md (100%) rename _docs/example-catalog/{ => ci-examples}/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md (100%) rename _docs/example-catalog/{java => ci-examples}/spring-boot-2.md (100%) rename _docs/example-catalog/{ => ci-examples}/uploading-or-downloading-from-gs.md (100%) rename _docs/example-catalog/{ => ci-examples}/vault-secrets-in-the-pipeline.md (100%) rename _docs/example-catalog/{python => ci-examples}/voting-app.md (100%) delete mode 100644 _docs/example-catalog/general/selenium-test.md delete mode 100644 _docs/example-catalog/nodejs/voting-app.md diff --git a/_data/nav.yml b/_data/nav.yml index 222c9ac3..f8d73493 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -196,10 +196,13 @@ -- title: "Example catalog" - url: "/example-catalog/examples" +- title: Example catalog + url: "/example-catalog" pages: - - title: "Git" + - title: "Examples" + url: "/examples" + - title: "CI examples" + url: "/ci-examples" sub-pages: - title: Checking out Git repositories url: "/git-checkout" @@ -209,8 +212,6 @@ url: "example-catalog/non-git-checkout" - title: Use Git Hash in CI url: "example-catalog/get-short-sha-id-and-use-it-in-a-ci-process" - - title: "Image builds" - sub-pages: - title: Build an Image with the Dockerfile in Root Directory url: "/build-an-image-dockerfile-in-root-directory" - title: Build an Image - Specify Dockerfile Location @@ -227,29 +228,18 @@ url: "/uploading-or-downloading-from-gs" - title: Calling other pipelines url: "/call-child-pipelines" - - title: Trigger a K8s Deployment from a DockerHub Push Event - url: "/trigger-a-k8s-deployment-from-docker-registry" - - title: "Testing" - url: "/examples" - sub-pages: - title: Run Unit Tests url: "/run-unit-tests" - title: Run Integration Tests url: "/run-integration-tests" - title: Fan-in/Fan-out Example with Unit Tests - url: "fan-in-fan-out" - - title: "Code Coverage" - url: "/examples" - sub-pages: - - title: Codecov Coverage Reports + url: "/fan-in-fan-out" + - title: Codecov Coverage Reports url: "/codecov-testing" - title: Coveralls Coverage Reports url: "/coveralls-testing" - title: Codacy Coverage Reports url: "/codacy-testing" - - title: "Databases" - url: "/examples" - sub-pages: - title: Run Integration Tests with Mongo url: "/integration-tests-with-mongo" - title: Run Integration Tests with MySQL @@ -264,10 +254,36 @@ url: "/shared-volumes-of-service-from-composition-step-for-other-yml-steps" - title: Import data to MongoDB url: "/import-data-to-mongodb" - - title: "Deployments" - url: "/examples" + - title: Vault Secrets in the Pipeline + url: "/vault-secrets-in-the-pipeline" + - title: Decryption with Mozilla SOPS + url: "/decryption-with-mozilla-sops" + - title: GitOps secrets + url: "/gitops-secrets" + - title: Launch Composition + url: "/launch-composition" + - title: Use Docker compose + url: "/launching-a-composition-and-defining-a-service-environment-variables-using-a-file" + - title: Sending the notification to Slack + url: "/sending-the-notification-to-slack" + - title: Sending the notification to Jira + url: "/sending-the-notification-to-jira" + - title: "CD examples" + url: "/cd-examples" sub-pages: - - title: Deploy to VM + - title: MongoDB preload data + url: "/import-data-to-mongodb" + - title: NodeJS + Angular2 + MongoDB + url: "/nodejs-angular2-mongodb" + - title: Secure a Docker Container Using HTTP Basic Auth + url: "/secure-a-docker-container-using-http-basic-auth" + - title: Spring Boot + Kafka + Zookeeper + url: "/spring-boot-kafka-zookeeper" + - title: Web terminal + url: "/web-terminal" + - title: Trigger a K8s Deployment from a DockerHub Push Event + url: "/trigger-a-k8s-deployment-from-docker-registry" + - title: Deploy to VM url: "/packer-gcloud" - title: Deploy to a VM using ftp url: "/transferring-php-ftp" @@ -292,44 +308,8 @@ - title: Amazon ECS/Fargate url: "/amazon-ecs" - title: Elastic Beanstalk - url: "/elastic-beanstalk" - - title: "Secrets" - url: "/examples" - sub-pages: - - title: Vault Secrets in the Pipeline - url: "/vault-secrets-in-the-pipeline" - - title: Decryption with Mozilla SOPS - url: "/decryption-with-mozilla-sops" - - title: GitOps secrets - url: "/gitops-secrets" - - title: "Compositions" - url: "/examples" - sub-pages: - - title: Launch Composition - url: "/launch-composition" - - title: Use Docker compose - url: "/launching-a-composition-and-defining-a-service-environment-variables-using-a-file" - - title: "Notifications" - url: "/examples" - sub-pages: - - title: Sending the notification to Slack - url: "/sending-the-notification-to-slack" - - title: Sending the notification to Jira - url: "/sending-the-notification-to-jira" - - title: "Security" - url: "/examples" - sub-pages: - - title: Secure a Docker Container Using HTTP Basic Auth - url: "/secure-a-docker-container-using-http-basic-auth" - - title: "General" - url: "/examples" - sub-pages: - - title: NodeJS + Angular2 + MongoDB - url: "/nodejs-angular2-mongodb" - - title: Spring Boot + Kafka + Zookeeper - url: "/spring-boot-kafka-zookeeper" - - title: Web terminal - url: "/web-terminal" + url: "/elastic-beanstalk" + diff --git a/_docs/example-catalog/amazon-ecs.md b/_docs/example-catalog/cd-examples/amazon-ecs.md similarity index 100% rename from _docs/example-catalog/amazon-ecs.md rename to _docs/example-catalog/cd-examples/amazon-ecs.md diff --git a/_docs/example-catalog/deploy-to-heroku.md b/_docs/example-catalog/cd-examples/deploy-to-heroku.md similarity index 100% rename from _docs/example-catalog/deploy-to-heroku.md rename to _docs/example-catalog/cd-examples/deploy-to-heroku.md diff --git a/_docs/example-catalog/deploy-to-tomcat-via-scp.md b/_docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp.md similarity index 100% rename from _docs/example-catalog/deploy-to-tomcat-via-scp.md rename to _docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp.md diff --git a/_docs/example-catalog/deploy-with-kustomize.md b/_docs/example-catalog/cd-examples/deploy-with-kustomize.md similarity index 100% rename from _docs/example-catalog/deploy-with-kustomize.md rename to _docs/example-catalog/cd-examples/deploy-with-kustomize.md diff --git a/_docs/example-catalog/docker-swarm.md b/_docs/example-catalog/cd-examples/docker-swarm.md similarity index 100% rename from _docs/example-catalog/docker-swarm.md rename to _docs/example-catalog/cd-examples/docker-swarm.md diff --git a/_docs/example-catalog/elastic-beanstalk.md b/_docs/example-catalog/cd-examples/elastic-beanstalk.md similarity index 100% rename from _docs/example-catalog/elastic-beanstalk.md rename to _docs/example-catalog/cd-examples/elastic-beanstalk.md diff --git a/_docs/example-catalog/helm.md b/_docs/example-catalog/cd-examples/helm.md similarity index 100% rename from _docs/example-catalog/helm.md rename to _docs/example-catalog/cd-examples/helm.md diff --git a/_docs/example-catalog/import-data-to-mongodb.md b/_docs/example-catalog/cd-examples/import-data-to-mongodb.md similarity index 100% rename from _docs/example-catalog/import-data-to-mongodb.md rename to _docs/example-catalog/cd-examples/import-data-to-mongodb.md diff --git a/_docs/example-catalog/nodejs-angular2-mongodb.md b/_docs/example-catalog/cd-examples/nodejs-angular2-mongodb.md similarity index 100% rename from _docs/example-catalog/nodejs-angular2-mongodb.md rename to _docs/example-catalog/cd-examples/nodejs-angular2-mongodb.md diff --git a/_docs/example-catalog/nomad.md b/_docs/example-catalog/cd-examples/nomad.md similarity index 100% rename from _docs/example-catalog/nomad.md rename to _docs/example-catalog/cd-examples/nomad.md diff --git a/_docs/example-catalog/packer-gcloud.md b/_docs/example-catalog/cd-examples/packer-gcloud.md similarity index 100% rename from _docs/example-catalog/packer-gcloud.md rename to _docs/example-catalog/cd-examples/packer-gcloud.md diff --git a/_docs/example-catalog/pulumi.md b/_docs/example-catalog/cd-examples/pulumi.md similarity index 100% rename from _docs/example-catalog/pulumi.md rename to _docs/example-catalog/cd-examples/pulumi.md diff --git a/_docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md b/_docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth.md similarity index 100% rename from _docs/example-catalog/secure-a-docker-container-using-http-basic-auth.md rename to _docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth.md diff --git a/_docs/example-catalog/spring-boot-kafka-zookeeper.md b/_docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper.md similarity index 100% rename from _docs/example-catalog/spring-boot-kafka-zookeeper.md rename to _docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper.md diff --git a/_docs/example-catalog/terraform.md b/_docs/example-catalog/cd-examples/terraform.md similarity index 100% rename from _docs/example-catalog/terraform.md rename to _docs/example-catalog/cd-examples/terraform.md diff --git a/_docs/example-catalog/transferring-php-ftp.md b/_docs/example-catalog/cd-examples/transferring-php-ftp.md similarity index 100% rename from _docs/example-catalog/transferring-php-ftp.md rename to _docs/example-catalog/cd-examples/transferring-php-ftp.md diff --git a/_docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md b/_docs/example-catalog/cd-examples/trigger-a-k8s-deployment-from-docker-registry.md similarity index 100% rename from _docs/example-catalog/trigger-a-k8s-deployment-from-docker-registry.md rename to _docs/example-catalog/cd-examples/trigger-a-k8s-deployment-from-docker-registry.md diff --git a/_docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md b/_docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step.md similarity index 100% rename from _docs/example-catalog/use-kubectl-as-part-of-freestyle-step.md rename to _docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step.md diff --git a/_docs/example-catalog/web-terminal.md b/_docs/example-catalog/cd-examples/web-terminal.md similarity index 100% rename from _docs/example-catalog/web-terminal.md rename to _docs/example-catalog/cd-examples/web-terminal.md diff --git a/_docs/example-catalog/mobile/android.md b/_docs/example-catalog/ci-examples/android.md similarity index 100% rename from _docs/example-catalog/mobile/android.md rename to _docs/example-catalog/ci-examples/android.md diff --git a/_docs/example-catalog/build-an-image-from-a-different-git-repository.md b/_docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository.md similarity index 100% rename from _docs/example-catalog/build-an-image-from-a-different-git-repository.md rename to _docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository.md diff --git a/_docs/example-catalog/build-an-image-specify-dockerfile-location.md b/_docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location.md similarity index 100% rename from _docs/example-catalog/build-an-image-specify-dockerfile-location.md rename to _docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location.md diff --git a/_docs/example-catalog/build-an-image-with-build-arguments.md b/_docs/example-catalog/ci-examples/build-an-image-with-build-arguments.md similarity index 100% rename from _docs/example-catalog/build-an-image-with-build-arguments.md rename to _docs/example-catalog/ci-examples/build-an-image-with-build-arguments.md diff --git a/_docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md b/_docs/example-catalog/ci-examples/build-an-image-with-the-dockerfile-in-root-directory.md similarity index 100% rename from _docs/example-catalog/build-an-image-with-the-dockerfile-in-root-directory.md rename to _docs/example-catalog/ci-examples/build-an-image-with-the-dockerfile-in-root-directory.md diff --git a/_docs/example-catalog/build-and-push-an-image.md b/_docs/example-catalog/ci-examples/build-and-push-an-image.md similarity index 100% rename from _docs/example-catalog/build-and-push-an-image.md rename to _docs/example-catalog/ci-examples/build-and-push-an-image.md diff --git a/_docs/example-catalog/cc/c-make.md b/_docs/example-catalog/ci-examples/c-make.md similarity index 100% rename from _docs/example-catalog/cc/c-make.md rename to _docs/example-catalog/ci-examples/c-make.md diff --git a/_docs/example-catalog/call-child-pipelines.md b/_docs/example-catalog/ci-examples/call-child-pipelines.md similarity index 100% rename from _docs/example-catalog/call-child-pipelines.md rename to _docs/example-catalog/ci-examples/call-child-pipelines.md diff --git a/_docs/example-catalog/cc.md b/_docs/example-catalog/ci-examples/cc.md similarity index 100% rename from _docs/example-catalog/cc.md rename to _docs/example-catalog/ci-examples/cc.md diff --git a/_docs/example-catalog/codacy-testing.md b/_docs/example-catalog/ci-examples/codacy-testing.md similarity index 100% rename from _docs/example-catalog/codacy-testing.md rename to _docs/example-catalog/ci-examples/codacy-testing.md diff --git a/_docs/example-catalog/codecov-testing.md b/_docs/example-catalog/ci-examples/codecov-testing.md similarity index 100% rename from _docs/example-catalog/codecov-testing.md rename to _docs/example-catalog/ci-examples/codecov-testing.md diff --git a/_docs/example-catalog/coveralls-testing.md b/_docs/example-catalog/ci-examples/coveralls-testing.md similarity index 100% rename from _docs/example-catalog/coveralls-testing.md rename to _docs/example-catalog/ci-examples/coveralls-testing.md diff --git a/_docs/example-catalog/cc/cpp-cmake.md b/_docs/example-catalog/ci-examples/cpp-cmake.md similarity index 100% rename from _docs/example-catalog/cc/cpp-cmake.md rename to _docs/example-catalog/ci-examples/cpp-cmake.md diff --git a/_docs/example-catalog/decryption-with-mozilla-sops.md b/_docs/example-catalog/ci-examples/decryption-with-mozilla-sops.md similarity index 100% rename from _docs/example-catalog/decryption-with-mozilla-sops.md rename to _docs/example-catalog/ci-examples/decryption-with-mozilla-sops.md diff --git a/_docs/example-catalog/python/django.md b/_docs/example-catalog/ci-examples/django.md similarity index 100% rename from _docs/example-catalog/python/django.md rename to _docs/example-catalog/ci-examples/django.md diff --git a/_docs/example-catalog/dotnet.md b/_docs/example-catalog/ci-examples/dotnet.md similarity index 100% rename from _docs/example-catalog/dotnet.md rename to _docs/example-catalog/ci-examples/dotnet.md diff --git a/_docs/example-catalog/examples.md b/_docs/example-catalog/ci-examples/examples.md similarity index 100% rename from _docs/example-catalog/examples.md rename to _docs/example-catalog/ci-examples/examples.md diff --git a/_docs/example-catalog/fan-in-fan-out.md b/_docs/example-catalog/ci-examples/fan-in-fan-out.md similarity index 100% rename from _docs/example-catalog/fan-in-fan-out.md rename to _docs/example-catalog/ci-examples/fan-in-fan-out.md diff --git a/_docs/example-catalog/general.md b/_docs/example-catalog/ci-examples/general.md similarity index 100% rename from _docs/example-catalog/general.md rename to _docs/example-catalog/ci-examples/general.md diff --git a/_docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md b/_docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process.md similarity index 100% rename from _docs/example-catalog/get-short-sha-id-and-use-it-in-a-ci-process.md rename to _docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process.md diff --git a/_docs/example-catalog/git-checkout-custom.md b/_docs/example-catalog/ci-examples/git-checkout-custom.md similarity index 100% rename from _docs/example-catalog/git-checkout-custom.md rename to _docs/example-catalog/ci-examples/git-checkout-custom.md diff --git a/_docs/example-catalog/git-checkout.md b/_docs/example-catalog/ci-examples/git-checkout.md similarity index 100% rename from _docs/example-catalog/git-checkout.md rename to _docs/example-catalog/ci-examples/git-checkout.md diff --git a/_docs/example-catalog/gitops-secrets.md b/_docs/example-catalog/ci-examples/gitops-secrets.md similarity index 100% rename from _docs/example-catalog/gitops-secrets.md rename to _docs/example-catalog/ci-examples/gitops-secrets.md diff --git a/_docs/example-catalog/golang/golang-hello-world.md b/_docs/example-catalog/ci-examples/golang-hello-world.md similarity index 100% rename from _docs/example-catalog/golang/golang-hello-world.md rename to _docs/example-catalog/ci-examples/golang-hello-world.md diff --git a/_docs/example-catalog/golang.md b/_docs/example-catalog/ci-examples/golang.md similarity index 100% rename from _docs/example-catalog/golang.md rename to _docs/example-catalog/ci-examples/golang.md diff --git a/_docs/example-catalog/golang/goreleaser.md b/_docs/example-catalog/ci-examples/goreleaser.md similarity index 100% rename from _docs/example-catalog/golang/goreleaser.md rename to _docs/example-catalog/ci-examples/goreleaser.md diff --git a/_docs/example-catalog/java/gradle.md b/_docs/example-catalog/ci-examples/gradle.md similarity index 100% rename from _docs/example-catalog/java/gradle.md rename to _docs/example-catalog/ci-examples/gradle.md diff --git a/_docs/example-catalog/integration-tests-with-mongo.md b/_docs/example-catalog/ci-examples/integration-tests-with-mongo.md similarity index 100% rename from _docs/example-catalog/integration-tests-with-mongo.md rename to _docs/example-catalog/ci-examples/integration-tests-with-mongo.md diff --git a/_docs/example-catalog/integration-tests-with-mysql.md b/_docs/example-catalog/ci-examples/integration-tests-with-mysql.md similarity index 100% rename from _docs/example-catalog/integration-tests-with-mysql.md rename to _docs/example-catalog/ci-examples/integration-tests-with-mysql.md diff --git a/_docs/example-catalog/integration-tests-with-postgres.md b/_docs/example-catalog/ci-examples/integration-tests-with-postgres.md similarity index 100% rename from _docs/example-catalog/integration-tests-with-postgres.md rename to _docs/example-catalog/ci-examples/integration-tests-with-postgres.md diff --git a/_docs/example-catalog/integration-tests-with-redis.md b/_docs/example-catalog/ci-examples/integration-tests-with-redis.md similarity index 100% rename from _docs/example-catalog/integration-tests-with-redis.md rename to _docs/example-catalog/ci-examples/integration-tests-with-redis.md diff --git a/_docs/example-catalog/java.md b/_docs/example-catalog/ci-examples/java.md similarity index 100% rename from _docs/example-catalog/java.md rename to _docs/example-catalog/ci-examples/java.md diff --git a/_docs/example-catalog/launch-composition.md b/_docs/example-catalog/ci-examples/launch-composition.md similarity index 100% rename from _docs/example-catalog/launch-composition.md rename to _docs/example-catalog/ci-examples/launch-composition.md diff --git a/_docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md b/_docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md similarity index 100% rename from _docs/example-catalog/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md rename to _docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md diff --git a/_docs/example-catalog/nodejs/lets-chat.md b/_docs/example-catalog/ci-examples/lets-chat.md similarity index 100% rename from _docs/example-catalog/nodejs/lets-chat.md rename to _docs/example-catalog/ci-examples/lets-chat.md diff --git a/_docs/example-catalog/mobile.md b/_docs/example-catalog/ci-examples/mobile.md similarity index 100% rename from _docs/example-catalog/mobile.md rename to _docs/example-catalog/ci-examples/mobile.md diff --git a/_docs/example-catalog/nodejs.md b/_docs/example-catalog/ci-examples/nodejs.md similarity index 100% rename from _docs/example-catalog/nodejs.md rename to _docs/example-catalog/ci-examples/nodejs.md diff --git a/_docs/example-catalog/non-git-checkout.md b/_docs/example-catalog/ci-examples/non-git-checkout.md similarity index 100% rename from _docs/example-catalog/non-git-checkout.md rename to _docs/example-catalog/ci-examples/non-git-checkout.md diff --git a/_docs/example-catalog/php.md b/_docs/example-catalog/ci-examples/php.md similarity index 100% rename from _docs/example-catalog/php.md rename to _docs/example-catalog/ci-examples/php.md diff --git a/_docs/example-catalog/populate-a-database-with-existing-data.md b/_docs/example-catalog/ci-examples/populate-a-database-with-existing-data.md similarity index 100% rename from _docs/example-catalog/populate-a-database-with-existing-data.md rename to _docs/example-catalog/ci-examples/populate-a-database-with-existing-data.md diff --git a/_docs/example-catalog/java/publish-jar.md b/_docs/example-catalog/ci-examples/publish-jar.md similarity index 100% rename from _docs/example-catalog/java/publish-jar.md rename to _docs/example-catalog/ci-examples/publish-jar.md diff --git a/_docs/example-catalog/python.md b/_docs/example-catalog/ci-examples/python.md similarity index 100% rename from _docs/example-catalog/python.md rename to _docs/example-catalog/ci-examples/python.md diff --git a/_docs/example-catalog/nodejs/react.md b/_docs/example-catalog/ci-examples/react.md similarity index 100% rename from _docs/example-catalog/nodejs/react.md rename to _docs/example-catalog/ci-examples/react.md diff --git a/_docs/example-catalog/ruby.md b/_docs/example-catalog/ci-examples/ruby.md similarity index 100% rename from _docs/example-catalog/ruby.md rename to _docs/example-catalog/ci-examples/ruby.md diff --git a/_docs/example-catalog/run-integration-tests.md b/_docs/example-catalog/ci-examples/run-integration-tests.md similarity index 100% rename from _docs/example-catalog/run-integration-tests.md rename to _docs/example-catalog/ci-examples/run-integration-tests.md diff --git a/_docs/example-catalog/run-unit-tests.md b/_docs/example-catalog/ci-examples/run-unit-tests.md similarity index 100% rename from _docs/example-catalog/run-unit-tests.md rename to _docs/example-catalog/ci-examples/run-unit-tests.md diff --git a/_docs/example-catalog/rust.md b/_docs/example-catalog/ci-examples/rust.md similarity index 100% rename from _docs/example-catalog/rust.md rename to _docs/example-catalog/ci-examples/rust.md diff --git a/_docs/example-catalog/scala/scala-hello-world.md b/_docs/example-catalog/ci-examples/scala-hello-world.md similarity index 100% rename from _docs/example-catalog/scala/scala-hello-world.md rename to _docs/example-catalog/ci-examples/scala-hello-world.md diff --git a/_docs/example-catalog/scala.md b/_docs/example-catalog/ci-examples/scala.md similarity index 100% rename from _docs/example-catalog/scala.md rename to _docs/example-catalog/ci-examples/scala.md diff --git a/_docs/example-catalog/sending-the-notification-to-jira.md b/_docs/example-catalog/ci-examples/sending-the-notification-to-jira.md similarity index 100% rename from _docs/example-catalog/sending-the-notification-to-jira.md rename to _docs/example-catalog/ci-examples/sending-the-notification-to-jira.md diff --git a/_docs/example-catalog/sending-the-notification-to-slack.md b/_docs/example-catalog/ci-examples/sending-the-notification-to-slack.md similarity index 100% rename from _docs/example-catalog/sending-the-notification-to-slack.md rename to _docs/example-catalog/ci-examples/sending-the-notification-to-slack.md diff --git a/_docs/example-catalog/shared-volumes-between-builds.md b/_docs/example-catalog/ci-examples/shared-volumes-between-builds.md similarity index 100% rename from _docs/example-catalog/shared-volumes-between-builds.md rename to _docs/example-catalog/ci-examples/shared-volumes-between-builds.md diff --git a/_docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md b/_docs/example-catalog/ci-examples/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md similarity index 100% rename from _docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md rename to _docs/example-catalog/ci-examples/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md diff --git a/_docs/example-catalog/java/spring-boot-2.md b/_docs/example-catalog/ci-examples/spring-boot-2.md similarity index 100% rename from _docs/example-catalog/java/spring-boot-2.md rename to _docs/example-catalog/ci-examples/spring-boot-2.md diff --git a/_docs/example-catalog/uploading-or-downloading-from-gs.md b/_docs/example-catalog/ci-examples/uploading-or-downloading-from-gs.md similarity index 100% rename from _docs/example-catalog/uploading-or-downloading-from-gs.md rename to _docs/example-catalog/ci-examples/uploading-or-downloading-from-gs.md diff --git a/_docs/example-catalog/vault-secrets-in-the-pipeline.md b/_docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline.md similarity index 100% rename from _docs/example-catalog/vault-secrets-in-the-pipeline.md rename to _docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline.md diff --git a/_docs/example-catalog/python/voting-app.md b/_docs/example-catalog/ci-examples/voting-app.md similarity index 100% rename from _docs/example-catalog/python/voting-app.md rename to _docs/example-catalog/ci-examples/voting-app.md diff --git a/_docs/example-catalog/general/selenium-test.md b/_docs/example-catalog/general/selenium-test.md deleted file mode 100644 index 424e22db..00000000 --- a/_docs/example-catalog/general/selenium-test.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: "Selenium test" -description: "" -excerpt: "" -group: example-catalog -sub_group: general -redirect_from: - - /docs/general/selenium-test/ -toc: true ---- -Using this repository, we'll help you get up to speed with basic functionality such as: compiling, testing and building Docker images. - -This project uses `JavaScript, Selenium, Protractor` to build an application which will eventually become a distributable Docker image. - -## Looking around -In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: - - `codefresh.yml` -{% highlight yaml %} -{% raw %} -version: '1.0' -steps: - build_image: - title: Building Image - type: build - dockerfile: Dockerfile - image_name: codefresh/selenium-test - - unit_test: - title: Unit Tests - type: composition - composition: - version: '2' - services: - selenium: - image: selenium/standalone-chrome:2.46.0 - ports: - - 4444:4444 - composition_candidates: - test: - image: ${{build_image}} - volumes: - - /dev/shm:/dev/shm - environment: - GITHUB_ACCOUNT: ${{GITHUB_ACCOUNT}} - GITHUB_PASSWORD: ${{GITHUB_PASSWORD}} - URL: 'https://codefresh.io' - SUITE: 'login' - command: bash -c '/protractor/run-tests.sh' - on_success: - metadata: - set: - - ${{build_image.imageId}}: - - CF_QUALITY: true - on_fail: - metadata: - set: - - ${{build_image.imageId}}: - - CF_QUALITY: false -{% endraw %} -{% endhighlight %} - -{% include image.html -lightbox="true" -file="/images/d0cb57c-codefresh_selenium_env_vars.png" -url="/images/d0cb57c-codefresh_selenium_env_vars.png" -alt="codefresh selenium env vars" -max-width="40%" -%} - -{{site.data.callout.callout_info}} -##### Example - -Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-selenium-test){:target="_blank"} in GitHub and follow the instructions there. -{{site.data.callout.end}} diff --git a/_docs/example-catalog/nodejs/voting-app.md b/_docs/example-catalog/nodejs/voting-app.md deleted file mode 100644 index 32b186e7..00000000 --- a/_docs/example-catalog/nodejs/voting-app.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "Voting app" -description: "" -excerpt: "" -group: example-catalog -sub_group: nodejs -redirect_from: - - /docs/voting-app/ - - /docs/nodejs/voting-app/ -toc: true ---- -This voting application is a demo with which you can build an advanced composition that uses `Python, Redis, Postgres, Node.js, and .Net`. - -The demo shows how to create a complex, micro-services application and push images to your docker registry. - -## Looking around -In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: - - `codefresh.yml` -{% highlight yaml %} -{% raw %} -version: '1.0' -steps: -#build all the images - build_image_vote: - title: Building Voting Image - type: build - #Important: rename this image to a valid repository in your registry. For example: myUserName/vote - image_name: containers101/vote - #The directory should be relative to git repository that is used for cloning - working_directory: ./vote/ - #Dockerfile location should be relative to the working directory - dockerfile: Dockerfile - - build_image_result: - title: Building Result Image - type: build - image_name: containers101/result - working_directory: ./result/ - dockerfile: Dockerfile - - build_image_worker: - title: Building Worker Image - type: build - image_name: containers101/worker - working_directory: ./worker/ - dockerfile: Dockerfile - - -#Push all the images - push_to_registry_vote: - title: Pushing to Vote Docker Registry - type: push - - #A candidate is the image that we want to push to registry - candidate: '${{build_image_vote}}' - - # You can push the image with whatever tag you want. In our example we use CF_BRANCH, which is a variable in - # the build process, accessible throughout the entire flow. - tag: '${{CF_BRANCH}}' - - push_to_registry_result: - title: Pushing to Result Docker Registry - type: push - candidate: '${{build_image_result}}' - tag: '${{CF_BRANCH}}' - - push_to_registry_worker: - title: Pushing to Worker Docker Registry - type: push - candidate: '${{build_image_worker}}' - tag: '${{CF_BRANCH}}' -{% endraw %} -{% endhighlight %} - -{{site.data.callout.callout_info}} -##### Example - -Just head over to the example [__repository__](https://github.com/containers101/voting-app){:target="_blank"} in GitHub and follow the instructions there. -{{site.data.callout.end}} - -## What to read next - -* [React example]({{site.baseurl}}/docs/learn-by-example/nodejs/react/) -* [Codefresh YAML]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) -* [Pipeline steps]({{site.baseurl}}/docs/codefresh-yaml/steps/) -* [Creating pipelines]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/) -* [How pipelines work]({{site.baseurl}}/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) \ No newline at end of file From 048f6198c7328bf012269b05dc327c6078f86155 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 15:44:49 +0200 Subject: [PATCH 05/17] Update nav.yml --- _data/nav.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/_data/nav.yml b/_data/nav.yml index f8d73493..2f4e9fe7 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -312,9 +312,6 @@ - - - - title: Reference url: "/reference" pages: From e0c8739ed79f5f8a773940e19b0f578dbf48a6fa Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 15:54:55 +0200 Subject: [PATCH 06/17] Update home and nav yamls --- _data/home-content.yml | 52 ++++++++++++++++++++++++++++++------------ _data/nav.yml | 4 ++-- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/_data/home-content.yml b/_data/home-content.yml index 18f73ad1..f6e9d505 100644 --- a/_data/home-content.yml +++ b/_data/home-content.yml @@ -116,20 +116,44 @@ icon: images/home-icons/administration.svg url: '' links: - - title: Manage users - localurl: /docs/administration/add-users/ - - title: Single Sign-On - localurl: /docs/administration/single-sign-on/ - - title: Set up OAuth2 authentication for Git providers - localurl: /docs/administration/oauth-setup/ - - title: User settings - localurl: /docs/administration/user-settings/ - - title: Access Control - localurl: /docs/administration/access-control/ - - title: Audit - localurl: /docs/administration/audit/ - - title: Codefresh IP addresses - localurl: /docs/administration/platform-ip-addresses/ + - title: Manage users + localurl: /docs/administration/add-users/ + - title: Single Sign-On + localurl: /docs/administration/single-sign-on/ + - title: Set up OAuth2 authentication for Git providers + localurl: /docs/administration/oauth-setup/ + - title: User settings + localurl: /docs/administration/user-settings/ + - title: Access Control + localurl: /docs/administration/access-control/ + - title: Audit + localurl: /docs/administration/audit/ + - title: Codefresh IP addresses + localurl: /docs/administration/platform-ip-addresses/ + +- title: Example catalog + icon: images/home-icons/tutorial.svg + url: '' + links: + - title: CI/CD examples for pipelines + localurl: /docs/example-catalog/examples/ + - title: Go + localurl: /docs/example-catalog/ci-examples/golang/ + - title: Java + localurl: /docs/example-catalog/java/ + - title: Node.js + localurl: /docs/example-catalog/nodejs/ + - title: Php + localurl: /docs/example-catalog/php/ + - title: Python + localurl: /docs/example-catalog/python/ + - title: Ruby On Rails + localurl: /docs/example-catalog/ruby/ + - title: C/C++ + localurl: /docs/example-catalog/cc/ + - title: C# (.NET core) + localurl: /docs/example-catalog/dotnet/ + - title: Reference icon: images/home-icons/guides.png diff --git a/_data/nav.yml b/_data/nav.yml index 2f4e9fe7..a07b4e4a 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -234,7 +234,7 @@ url: "/run-integration-tests" - title: Fan-in/Fan-out Example with Unit Tests url: "/fan-in-fan-out" - - title: Codecov Coverage Reports + - title: Codecov Coverage Reports url: "/codecov-testing" - title: Coveralls Coverage Reports url: "/coveralls-testing" @@ -283,7 +283,7 @@ url: "/web-terminal" - title: Trigger a K8s Deployment from a DockerHub Push Event url: "/trigger-a-k8s-deployment-from-docker-registry" - - title: Deploy to VM + - title: Deploy to VM url: "/packer-gcloud" - title: Deploy to a VM using ftp url: "/transferring-php-ftp" From 245e51aaf818c5273fafecc6dcdc9812d8dce6e4 Mon Sep 17 00:00:00 2001 From: NimRegev Date: Mon, 5 Dec 2022 16:57:05 +0200 Subject: [PATCH 07/17] Add images for examples --- _data/nav.yml | 8 +- .../amazon-ecs/ecs-pipeline-deployment.png | Bin 0 -> 149420 bytes images/examples/amazon-ecs/ecs-variables.png | Bin 0 -> 63280 bytes .../checkout/add-new-microservice.png | Bin 0 -> 36843 bytes .../checkout/add-new-microservice.svg | 1348 +++++++++++++++++ images/examples/checkout/simulate-trigger.png | Bin 0 -> 16139 bytes .../launch-composition-example.png | Bin 0 -> 88377 bytes .../deployments/heroku-deployer-pipeline.png | Bin 0 -> 24621 bytes .../deployments/heroku-deployer-variables.png | Bin 0 -> 22204 bytes .../heroku-deployer-variables2.png | Bin 0 -> 24433 bytes .../heroku-vanilla-push-pipeline.png | Bin 0 -> 30160 bytes .../k8s-deployment-CD-pipeline.png | Bin 0 -> 196608 bytes .../k8s-deployment-ci-pipeline.png | Bin 0 -> 404628 bytes .../deployments/k8s-kustomize-dashboard.png | Bin 0 -> 163136 bytes .../deployments/k8s-kustomize-pipeline.png | Bin 0 -> 282660 bytes .../k8s-kustomize-prod-endpoint.png | Bin 0 -> 151762 bytes .../k8s-kustomize-prod-pipeline.png | Bin 0 -> 265678 bytes .../k8s-kustomize-staging-endpoint.png | Bin 0 -> 156887 bytes .../k8s-kustomize-staging-pipeline.png | Bin 0 -> 265419 bytes .../examples/deployments/scp-hello-world.png | Bin 0 -> 9809 bytes images/examples/deployments/scp-pipeline.png | Bin 0 -> 24205 bytes images/examples/deployments/scp-variables.png | Bin 0 -> 21826 bytes .../docker-build/auto-push-to-cfcr.png | Bin 0 -> 134857 bytes .../docker-build/build-and-push-pipeline.png | Bin 0 -> 112659 bytes .../docker-build/build-dockerfile-root.png | Bin 0 -> 123040 bytes .../build-from-other-git-repo.png | Bin 0 -> 40663 bytes .../docker-build/build-spefify-dockerfile.png | Bin 0 -> 120246 bytes images/examples/docker-build/cfcr-layers.png | Bin 0 -> 246652 bytes .../docker-build/docker-build-arguments.png | Bin 0 -> 171864 bytes .../docker-build/two-docker-images.png | Bin 0 -> 41642 bytes .../docker-swarm/docker-swarm-pipeline.png | Bin 0 -> 34200 bytes images/examples/gs/gs-download-pipeline.png | Bin 0 -> 175598 bytes images/examples/gs/gs-pipeline-vars.png | Bin 0 -> 67945 bytes images/examples/gs/gs-upload-pipeline.png | Bin 0 -> 166656 bytes images/examples/helm/helm-chart.png | Bin 0 -> 11782 bytes images/examples/helm/helm-deploy-pipeline.png | Bin 0 -> 40284 bytes .../helm/helm-push-and-deploy-pipeline.png | Bin 0 -> 63114 bytes images/examples/helm/helm-release.png | Bin 0 -> 38267 bytes .../helm/import-helm-configuration.png | Bin 0 -> 16721 bytes .../integration-tests/integration-tests.png | Bin 0 -> 89250 bytes .../mongodb-integration-tests.png | Bin 0 -> 76282 bytes .../mysql-integration-tests.png | Bin 0 -> 63820 bytes .../postgresql-integration-tests.png | Bin 0 -> 72561 bytes .../integration-tests/preload-data-to-db.png | Bin 0 -> 122547 bytes .../redis-integration-tests.png | Bin 0 -> 112990 bytes .../nested-pipelines/call-other-pipeline.png | Bin 0 -> 123686 bytes images/examples/nomad/.keep | 0 images/examples/nomad/nomad-ci-pipeline.png | Bin 0 -> 93934 bytes images/examples/nomad/nomad-ui-deployment.png | Bin 0 -> 52344 bytes images/examples/nomad/nomad-variables.png | Bin 0 -> 13801 bytes images/examples/packer-gcloud/.keep | 0 .../packer-codefresh-pipeline.png | Bin 0 -> 117300 bytes .../service-account-variable.png | Bin 0 -> 18669 bytes images/examples/packer-gcloud/web-app-url.png | Bin 0 -> 18870 bytes .../examples/php-file-transfer/pipeline.png | Bin 0 -> 24772 bytes .../examples/php-file-transfer/variables.png | Bin 0 -> 21627 bytes .../examples/pulumi/pulumi-access-token.png | Bin 0 -> 21502 bytes images/examples/pulumi/pulumi-pipeline.png | Bin 0 -> 82319 bytes .../examples/scala/multi-stage-pipeline.png | Bin 0 -> 21087 bytes images/examples/scala/pipeline.png | Bin 0 -> 25716 bytes .../examples/scala/single-stage-pipeline.png | Bin 0 -> 24797 bytes images/examples/sealed-secrets/add-app.png | Bin 0 -> 114225 bytes .../examples/sealed-secrets/app-secrets.png | Bin 0 -> 371042 bytes .../examples/sealed-secrets/current-state.png | Bin 0 -> 210575 bytes .../secrets/mozilla-sops-pipeline-vars.png | Bin 0 -> 15080 bytes .../secrets/mozilla-sops-pipeline.png | Bin 0 -> 27867 bytes images/examples/secrets/vault-pipeline.png | Bin 0 -> 20813 bytes images/examples/secrets/vault-pipeline2.png | Bin 0 -> 6256 bytes .../examples/shared-workspace/volume-list.png | Bin 0 -> 135008 bytes .../examples/terraform/google_cloud_json.png | Bin 0 -> 14622 bytes .../examples/terraform/terraform-pipeline.png | Bin 0 -> 81284 bytes .../unit-tests/fan-in-fan-out-pipeline.png | Bin 0 -> 530506 bytes .../unit-tests/parallel-pipeline-examples.png | Bin 0 -> 26770 bytes .../unit-tests/unit-tests-pipeline.png | Bin 0 -> 96431 bytes 74 files changed, 1352 insertions(+), 4 deletions(-) create mode 100644 images/examples/amazon-ecs/ecs-pipeline-deployment.png create mode 100644 images/examples/amazon-ecs/ecs-variables.png create mode 100644 images/examples/checkout/add-new-microservice.png create mode 100644 images/examples/checkout/add-new-microservice.svg create mode 100644 images/examples/checkout/simulate-trigger.png create mode 100644 images/examples/composition/launch-composition-example.png create mode 100644 images/examples/deployments/heroku-deployer-pipeline.png create mode 100644 images/examples/deployments/heroku-deployer-variables.png create mode 100644 images/examples/deployments/heroku-deployer-variables2.png create mode 100644 images/examples/deployments/heroku-vanilla-push-pipeline.png create mode 100644 images/examples/deployments/k8s-deployment-CD-pipeline.png create mode 100644 images/examples/deployments/k8s-deployment-ci-pipeline.png create mode 100644 images/examples/deployments/k8s-kustomize-dashboard.png create mode 100644 images/examples/deployments/k8s-kustomize-pipeline.png create mode 100644 images/examples/deployments/k8s-kustomize-prod-endpoint.png create mode 100644 images/examples/deployments/k8s-kustomize-prod-pipeline.png create mode 100644 images/examples/deployments/k8s-kustomize-staging-endpoint.png create mode 100644 images/examples/deployments/k8s-kustomize-staging-pipeline.png create mode 100644 images/examples/deployments/scp-hello-world.png create mode 100644 images/examples/deployments/scp-pipeline.png create mode 100644 images/examples/deployments/scp-variables.png create mode 100644 images/examples/docker-build/auto-push-to-cfcr.png create mode 100644 images/examples/docker-build/build-and-push-pipeline.png create mode 100644 images/examples/docker-build/build-dockerfile-root.png create mode 100644 images/examples/docker-build/build-from-other-git-repo.png create mode 100644 images/examples/docker-build/build-spefify-dockerfile.png create mode 100644 images/examples/docker-build/cfcr-layers.png create mode 100644 images/examples/docker-build/docker-build-arguments.png create mode 100644 images/examples/docker-build/two-docker-images.png create mode 100644 images/examples/docker-swarm/docker-swarm-pipeline.png create mode 100644 images/examples/gs/gs-download-pipeline.png create mode 100644 images/examples/gs/gs-pipeline-vars.png create mode 100644 images/examples/gs/gs-upload-pipeline.png create mode 100644 images/examples/helm/helm-chart.png create mode 100644 images/examples/helm/helm-deploy-pipeline.png create mode 100644 images/examples/helm/helm-push-and-deploy-pipeline.png create mode 100644 images/examples/helm/helm-release.png create mode 100644 images/examples/helm/import-helm-configuration.png create mode 100644 images/examples/integration-tests/integration-tests.png create mode 100644 images/examples/integration-tests/mongodb-integration-tests.png create mode 100644 images/examples/integration-tests/mysql-integration-tests.png create mode 100644 images/examples/integration-tests/postgresql-integration-tests.png create mode 100644 images/examples/integration-tests/preload-data-to-db.png create mode 100644 images/examples/integration-tests/redis-integration-tests.png create mode 100644 images/examples/nested-pipelines/call-other-pipeline.png create mode 100644 images/examples/nomad/.keep create mode 100644 images/examples/nomad/nomad-ci-pipeline.png create mode 100644 images/examples/nomad/nomad-ui-deployment.png create mode 100644 images/examples/nomad/nomad-variables.png create mode 100644 images/examples/packer-gcloud/.keep create mode 100644 images/examples/packer-gcloud/packer-codefresh-pipeline.png create mode 100644 images/examples/packer-gcloud/service-account-variable.png create mode 100644 images/examples/packer-gcloud/web-app-url.png create mode 100644 images/examples/php-file-transfer/pipeline.png create mode 100644 images/examples/php-file-transfer/variables.png create mode 100644 images/examples/pulumi/pulumi-access-token.png create mode 100644 images/examples/pulumi/pulumi-pipeline.png create mode 100644 images/examples/scala/multi-stage-pipeline.png create mode 100644 images/examples/scala/pipeline.png create mode 100644 images/examples/scala/single-stage-pipeline.png create mode 100644 images/examples/sealed-secrets/add-app.png create mode 100644 images/examples/sealed-secrets/app-secrets.png create mode 100644 images/examples/sealed-secrets/current-state.png create mode 100644 images/examples/secrets/mozilla-sops-pipeline-vars.png create mode 100644 images/examples/secrets/mozilla-sops-pipeline.png create mode 100644 images/examples/secrets/vault-pipeline.png create mode 100644 images/examples/secrets/vault-pipeline2.png create mode 100644 images/examples/shared-workspace/volume-list.png create mode 100644 images/examples/terraform/google_cloud_json.png create mode 100644 images/examples/terraform/terraform-pipeline.png create mode 100644 images/examples/unit-tests/fan-in-fan-out-pipeline.png create mode 100644 images/examples/unit-tests/parallel-pipeline-examples.png create mode 100644 images/examples/unit-tests/unit-tests-pipeline.png diff --git a/_data/nav.yml b/_data/nav.yml index a07b4e4a..b4e93928 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -207,13 +207,13 @@ - title: Checking out Git repositories url: "/git-checkout" - title: Custom Git commmands - url: "/example-catalog/git-checkout-custom" + url: "/git-checkout-custom" - title: Non-Git checkouts - url: "example-catalog/non-git-checkout" + url: "/non-git-checkout" - title: Use Git Hash in CI - url: "example-catalog/get-short-sha-id-and-use-it-in-a-ci-process" + url: "/get-short-sha-id-and-use-it-in-a-ci-process" - title: Build an Image with the Dockerfile in Root Directory - url: "/build-an-image-dockerfile-in-root-directory" + url: "/build-an-image-with-the-dockerfile-in-root-directory" - title: Build an Image - Specify Dockerfile Location url: "/build-an-image-specify-dockerfile-location" - title: Build an Image from a Different Git Repository diff --git a/images/examples/amazon-ecs/ecs-pipeline-deployment.png b/images/examples/amazon-ecs/ecs-pipeline-deployment.png new file mode 100644 index 0000000000000000000000000000000000000000..cc4d3347d40a39497e1b2a37e6da611a5216130a GIT binary patch literal 149420 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 z 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
  • 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ⅇ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 T-{=oh@U?gMewC-n7JmN^o#(l+ literal 0 HcmV?d00001 diff --git a/images/examples/amazon-ecs/ecs-variables.png b/images/examples/amazon-ecs/ecs-variables.png new file mode 100644 index 0000000000000000000000000000000000000000..f9bc5fa162e7841557ba9d7d92fcdf42d791b95e GIT binary patch literal 63280 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 dF)CZfr@oz@wW)cgYAl04>x?%T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + +   + step + + +   + + + Pipeline + + +   + step + + + +   + step + + + + Trigger 1 + + + + + Trigger 2 + + + + Trigger 3 + + + + Trigger 4 + + + + + + + Microservice N + + Trigger N + + + + diff --git a/images/examples/checkout/simulate-trigger.png b/images/examples/checkout/simulate-trigger.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4da4ff4639ed61253356107d46c1a6d2fb3d55 GIT binary patch literal 16139 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 literal 0 HcmV?d00001 diff --git a/images/examples/composition/launch-composition-example.png b/images/examples/composition/launch-composition-example.png new file mode 100644 index 0000000000000000000000000000000000000000..ff5068a1efe2a3db512ffac2bf6c5c565bec5008 GIT binary patch literal 88377 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 literal 0 HcmV?d00001 diff --git a/images/examples/deployments/heroku-deployer-pipeline.png b/images/examples/deployments/heroku-deployer-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..3189634c49861393887862be9d08b05c5ac2a248 GIT binary patch literal 24621 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 literal 0 HcmV?d00001 diff --git a/images/examples/deployments/heroku-deployer-variables.png b/images/examples/deployments/heroku-deployer-variables.png new file mode 100644 index 0000000000000000000000000000000000000000..7fff37fbdee47f60c429b0dd4c76a21cf3afbe22 GIT binary patch literal 22204 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 literal 0 HcmV?d00001 diff --git a/images/examples/deployments/k8s-deployment-CD-pipeline.png b/images/examples/deployments/k8s-deployment-CD-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..551ff8404b2c9211b8cf23d872fd0a937658cb2a GIT binary patch literal 196608 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

    ^ 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