From 197f00cc3bb95c3133eead831acde4e1f25eeb53 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Tue, 6 Jun 2017 22:25:13 +0000 Subject: Add new directory --- .../how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d -- cgit v1.2.1 From 0f76c9eadbce4a49e7a5e68cb89382df71a6520a Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Tue, 6 Jun 2017 22:33:44 +0000 Subject: Add new file --- .../index.md | 167 +++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md new file mode 100644 index 00000000000..31bac149245 --- /dev/null +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -0,0 +1,167 @@ +> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || +> **Level:** intermediary || +> **Author:** [Fabio busatto](https://gitlab.com/bikebilly) || +> **Publication date:** AAAA/MM/DD + +In this article, we're going to show how we can leverage the power of GitLab CI to compile, test and deploy a Maven application to an Artifactory repository with just a very few lines of configuration. + +Every time we change our sample application, the Continuos Integration will check that everything is correct, and after a merge to master branch it will automatically push our package, making it ready for use. + + +# Create a simple Maven application + +First of all, we need to create our application. We choose to have a very simple one, but it could be any Maven application. The simplest way is to use Maven itself, we've just to run the following command: + +```bash +mvn archetype:generate -DgroupId=com.example.app -DartifactId=maven-example-app -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +``` + +Done! Let's move into the maven-example-app directory. Now we've our app to work with. + +The project structure is quite simple, and we're interested mainly in these resources: + +`pom.xml`: project object model (POM) file +`src/main/java/com/example/app/App.java`: source of our application (it prints "Hello World!" to stdout) + +# Test our app locally + +If we want to be sure the application has been created correctly, we can compile and test it: + +```bash +mvn compile && mvn test +``` + +Note: every time we run a `mvn` command it may happen that a bunch of files are downloaded: it's totally normal, and these files are cached so we don't have to download them again next time. + +At the end of the run, we should see an output like this: + +``` +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 5.614 s +[INFO] Finished at: 2017-06-05T10:50:36+02:00 +[INFO] Final Memory: 17M/130M +[INFO] ------------------------------------------------------------------------ +``` + +# Create `.gitlab-ci.yml` + +A very simple `.gitlab-ci.yml` file that performs build and tests of our application is the following: + +```yaml +image: maven:latest + +cache: + paths: + - target/ + +build: + script: + - mvn compile + +test: + script: + - mvn test +``` + +We want to use the latest docker image available for Maven, that already contains everything we need to perform our tasks. We also want to cache the `.m2` folder in the user homedir: this is the place where all the files automatically download by Maven commands are stored, so we can reuse them between stages. The `target` folder is where our application will be created: Maven runs all the phases in a specific order, so running `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances caching everything that is reused. + +# Push the code to GitLab + +Now that we've our app, we want to put it on GitLab! Long story short, we've to create a new project and push the code to it as usual. A new pipeline will run and you've just to wait until it succeed! + +# Set up Artifactory as the deployment repo + +## Configure POM file + +Next step is to setup our project to use Artifactory as its repository for artifacts deployment: in order to complete this, we need access to the Artifactory instance. +So, first of all let's select the `libs-release-local` repository in the `Set Me Up` section, and copy to clipboard the configuration snipped marked as `Deploy`. This is the "address" of our repo, and it is needed by Maven to push artifacts during the `deploy` stage. +Now let's go back to our project and edit the pom.xml file: we have to add the snipped we just copied from Artifactory into the project section, so we can paste it after the dependencies. +The final POM will look like this: + +```xml + + 4.0.0 + com.example.app + maven-example-app + jar + 1.0 + maven-example-app + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + + central + 0072a36394cd-releases + http://localhost:8081/artifactory/libs-release-local + + + +``` + +## Configure credentials for the repo + +One last step is required to actully deploy artifacts to Artifactory: we need to configure credentials for our repo, and best practices want us to create an API key for this task, so we don't have to expose our account password. +Let's go back to Artifactory, edit the account settings and generate a new API key. For security reasons, we don't want to expose directly this key into the `.gitlab-ci.yml, so we're going to create secret variables REPO_USERNAME and REPO_PASSWORD containing the username and the key in our GitLab project settings. + +[screenshot of secret variables window] + +We must now include these credentials in the `~/.m2/settings.xml` file, so let's create a file named `.maven-settings.xml` in our project folder with the following content: + +```xml + + + + ${REPO_USERNAME} + ${REPO_PASSWORD} + central + + + +``` + +Note that `id` must have the same value as the related `id` field of the `repository` section in `pom.xml`. + +# Configure automatic deployment + +Time to change `.gitlab-ci.yml` and add the deploy stage! Maven has the perfect command for that, but it requires `settings.xml` to be in the correct folder, so we need to move it before executing `mvn deploy` command. + +The complete file is now this: + +```yaml +image: maven:latest + +cache: + paths: + - target/ + +Build: + Stage: build + script: + - mvn compile + +Test: + Stage: test + script: + - mvn test + +Deploy: + Stage: deploy + script: + - cp .maven-settings.xml ~/.m2/settings.xml + - mvn deploy + only: + - master +``` + +We're ready to go! Every merge (or push) to master will now trigger the deployment to our Artifactory repository! \ No newline at end of file -- cgit v1.2.1 From a320af5febee6bda490c7d87755bbc4d9cc610db Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Tue, 6 Jun 2017 22:37:20 +0000 Subject: Update index.md --- .../index.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 31bac149245..77718077f37 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -1,6 +1,6 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || > **Level:** intermediary || -> **Author:** [Fabio busatto](https://gitlab.com/bikebilly) || +> **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || > **Publication date:** AAAA/MM/DD In this article, we're going to show how we can leverage the power of GitLab CI to compile, test and deploy a Maven application to an Artifactory repository with just a very few lines of configuration. @@ -20,14 +20,14 @@ Done! Let's move into the maven-example-app directory. Now we've our app to work The project structure is quite simple, and we're interested mainly in these resources: -`pom.xml`: project object model (POM) file -`src/main/java/com/example/app/App.java`: source of our application (it prints "Hello World!" to stdout) +- `pom.xml`: project object model (POM) file +- `src/main/java/com/example/app/App.java`: source of our application (it prints "Hello World!" to stdout) # Test our app locally If we want to be sure the application has been created correctly, we can compile and test it: -```bash +``` mvn compile && mvn test ``` @@ -145,23 +145,22 @@ cache: paths: - target/ -Build: - Stage: build +build: + stage: build script: - mvn compile -Test: - Stage: test +test: + stage: test script: - mvn test -Deploy: - Stage: deploy +deploy: + stage: deploy script: - cp .maven-settings.xml ~/.m2/settings.xml - mvn deploy only: - master ``` - We're ready to go! Every merge (or push) to master will now trigger the deployment to our Artifactory repository! \ No newline at end of file -- cgit v1.2.1 From 0abb83c0acaab15891bd18de879debc5c6cc40f8 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Mon, 26 Jun 2017 15:15:41 +0000 Subject: Update index.md --- .../index.md | 124 +++++++++++---------- 1 file changed, 66 insertions(+), 58 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 77718077f37..53eebcfdcd2 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -3,78 +3,86 @@ > **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || > **Publication date:** AAAA/MM/DD -In this article, we're going to show how we can leverage the power of GitLab CI to compile, test and deploy a Maven application to an Artifactory repository with just a very few lines of configuration. - -Every time we change our sample application, the Continuos Integration will check that everything is correct, and after a merge to master branch it will automatically push our package, making it ready for use. - - -# Create a simple Maven application - -First of all, we need to create our application. We choose to have a very simple one, but it could be any Maven application. The simplest way is to use Maven itself, we've just to run the following command: - -```bash -mvn archetype:generate -DgroupId=com.example.app -DartifactId=maven-example-app -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false -``` +## Index -Done! Let's move into the maven-example-app directory. Now we've our app to work with. - -The project structure is quite simple, and we're interested mainly in these resources: - -- `pom.xml`: project object model (POM) file -- `src/main/java/com/example/app/App.java`: source of our application (it prints "Hello World!" to stdout) - -# Test our app locally - -If we want to be sure the application has been created correctly, we can compile and test it: - -``` -mvn compile && mvn test -``` +1. [Get a simple Maven application](#get-a-simple-maven-application) +1. [Configure Continuous Integration with `.gitlab-ci.yml`](#configure-continuous-integration-with-gitlab-ciyml) +1. [Set up Artifactory as the deployment repo](#set-up-artifactory-as-the-deployment-repo) +1. [Configure automatic deployment](#configure-automatic-deployment) -Note: every time we run a `mvn` command it may happen that a bunch of files are downloaded: it's totally normal, and these files are cached so we don't have to download them again next time. - -At the end of the run, we should see an output like this: - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 5.614 s -[INFO] Finished at: 2017-06-05T10:50:36+02:00 -[INFO] Final Memory: 17M/130M -[INFO] ------------------------------------------------------------------------ -``` +In this article, we're going to see how we can leverage the power of GitLab Continuous Integration features to compile and test a Maven application, +and finally deploy it to an Artifactory repository with just a very few lines of configuration. + +Every time we change our sample application, GitLab checks that the new version is still bug free, and after merging to `master` branch it will automatically push the new package +to the remote Artifactory repository, making it ready to use. + +## Get a simple Maven application + +First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. + +For this article we'll use a Maven app that can be cloned at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`, so let's login into our GitLab account and create a new project +with `Import project from` -> `Repo by URL`. + +This application is nothing more than a basic Hello World with a stub for a JUnit based test suite. It was created with the `maven-archetype-quickstart` Maven template. +The project structure is really simple, and we're mainly interested in these two resources: +- `pom.xml`: project object model (POM) file - here we've the configuration for our project +- `src/main/java/com/example/app/App.java`: source of our application - it prints "Hello World!" to stdout + +## Configure Continuous Integration with `.gitlab-ci.yml` + +Now that we've our application, we need to define stages that will build and test it automatically. In order to achieve this result, we create a file named `.gitlab-ci.yml` in the root of our git repository, once pushed this file will instruct the runner with all the commands needed. + +Let's see the content of the file: -# Create `.gitlab-ci.yml` - -A very simple `.gitlab-ci.yml` file that performs build and tests of our application is the following: - ```yaml image: maven:latest - + cache: paths: - target/ - + build: + stage: build script: - mvn compile - + test: + stage: test script: - mvn test ``` +We want to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Caching the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a specific order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances caching everything that is already created in a previous step. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. + +If you're creating the file using the GitLab UI, you just have to commit directly into `master`. Otherwise, if you cloned locally your brand new project, commit and push to remote. + +Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's wait until the pipeline ends, and we should see something like the following text in the job output log. + +``` +Running com.example.app.AppTest +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.049 sec + +Results : + +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 + +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 13.165 s +[INFO] Finished at: 2017-06-26T14:26:43Z +[INFO] Final Memory: 17M/147M +[INFO] ------------------------------------------------------------------------ +Creating cache default... +Created cache +Job succeeded +``` + +**Note**: the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log. + +## Set up Artifactory as the deployment repo -We want to use the latest docker image available for Maven, that already contains everything we need to perform our tasks. We also want to cache the `.m2` folder in the user homedir: this is the place where all the files automatically download by Maven commands are stored, so we can reuse them between stages. The `target` folder is where our application will be created: Maven runs all the phases in a specific order, so running `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances caching everything that is reused. - -# Push the code to GitLab - -Now that we've our app, we want to put it on GitLab! Long story short, we've to create a new project and push the code to it as usual. A new pipeline will run and you've just to wait until it succeed! - -# Set up Artifactory as the deployment repo - -## Configure POM file - +### Configure POM file + Next step is to setup our project to use Artifactory as its repository for artifacts deployment: in order to complete this, we need access to the Artifactory instance. So, first of all let's select the `libs-release-local` repository in the `Set Me Up` section, and copy to clipboard the configuration snipped marked as `Deploy`. This is the "address" of our repo, and it is needed by Maven to push artifacts during the `deploy` stage. Now let's go back to our project and edit the pom.xml file: we have to add the snipped we just copied from Artifactory into the project section, so we can paste it after the dependencies. @@ -108,7 +116,7 @@ The final POM will look like this: ``` -## Configure credentials for the repo +### Configure credentials for the repo One last step is required to actully deploy artifacts to Artifactory: we need to configure credentials for our repo, and best practices want us to create an API key for this task, so we don't have to expose our account password. Let's go back to Artifactory, edit the account settings and generate a new API key. For security reasons, we don't want to expose directly this key into the `.gitlab-ci.yml, so we're going to create secret variables REPO_USERNAME and REPO_PASSWORD containing the username and the key in our GitLab project settings. @@ -132,7 +140,7 @@ We must now include these credentials in the `~/.m2/settings.xml` file, so let's Note that `id` must have the same value as the related `id` field of the `repository` section in `pom.xml`. -# Configure automatic deployment +## Configure automatic deployment Time to change `.gitlab-ci.yml` and add the deploy stage! Maven has the perfect command for that, but it requires `settings.xml` to be in the correct folder, so we need to move it before executing `mvn deploy` command. -- cgit v1.2.1 From 2da50a7ec2084e9bb35546e9f3ae7f0bd913ab2d Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Wed, 28 Jun 2017 11:06:24 +0000 Subject: Update index.md --- .../index.md | 250 ++++++++++++--------- 1 file changed, 143 insertions(+), 107 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 53eebcfdcd2..4c11257e1eb 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -5,32 +5,86 @@ ## Index -1. [Get a simple Maven application](#get-a-simple-maven-application) -1. [Configure Continuous Integration with `.gitlab-ci.yml`](#configure-continuous-integration-with-gitlab-ciyml) -1. [Set up Artifactory as the deployment repo](#set-up-artifactory-as-the-deployment-repo) -1. [Configure automatic deployment](#configure-automatic-deployment) +## Introduction -In this article, we're going to see how we can leverage the power of GitLab Continuous Integration features to compile and test a Maven application, -and finally deploy it to an Artifactory repository with just a very few lines of configuration. +In this article, we're going to see how we can leverage the power of [GitLab Continuous Integration](https://about.gitlab.com/features/gitlab-ci-cd/) to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/) and then use it from another Maven application as a dependency. -Every time we change our sample application, GitLab checks that the new version is still bug free, and after merging to `master` branch it will automatically push the new package -to the remote Artifactory repository, making it ready to use. +We're going to create two different projects: +- `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) +- `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) -## Get a simple Maven application +We assume that we already have a GitLab account on [GitLab.com](https://gitlab.com/), and that we know the basic usage of CI. +We also assume that an Artifactory instance is available and reachable from the Internet, and that we've valid credentials to deploy on it. -First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. +## Create the simple Maven dependency -For this article we'll use a Maven app that can be cloned at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`, so let's login into our GitLab account and create a new project -with `Import project from` -> `Repo by URL`. +#### Get the sources + +First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. This will be our dependency we want to package and deploy to Artifactory, in order to be available to other projects. + +For this article we'll use a Maven app that can be cloned at `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, so let's login into our GitLab account and create a new project +with **Import project from ➔ Repo by URL**. + +This application is nothing more than a basic class with a stub for a JUnit based test suite. +It exposes a method called `hello` that accepts a string as input, and prints an hello message on the screen. -This application is nothing more than a basic Hello World with a stub for a JUnit based test suite. It was created with the `maven-archetype-quickstart` Maven template. The project structure is really simple, and we're mainly interested in these two resources: -- `pom.xml`: project object model (POM) file - here we've the configuration for our project -- `src/main/java/com/example/app/App.java`: source of our application - it prints "Hello World!" to stdout +- `pom.xml`: project object model (POM) configuration file +- `src/main/java/com/example/dep/Dep.java`: source of our application + +#### Configure Artifactory deployment + +The application is ready to use, but we need some additional steps for deploying it to Artifactory: +1. login to Artifactory with your user's credentials +2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel +3. copy to clipboard the configuration snippet under the **Deploy** paragraph -## Configure Continuous Integration with `.gitlab-ci.yml` +The snippet should look like this: + +```xml + + + central + 83d43b5afeb5-releases + ${repoURL}/libs-release-local + + +``` +**Note**: `url` has been added in order to make it configurable but could be kept static, we'll see later how to use secret variables for this. -Now that we've our application, we need to define stages that will build and test it automatically. In order to achieve this result, we create a file named `.gitlab-ci.yml` in the root of our git repository, once pushed this file will instruct the runner with all the commands needed. +Now let's copy the snippet in the `pom.xml` file for our project, just after the `dependencies` section. Easy! + +Another step we need to do before we can deploy our dependency to Artifactory is to configure authentication data. It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. Since we want to use GitLab Runner to automatically deploy the application, we should create the file in our project home and then move it to the proper location with a specific command in the `.gitlab-ci.yml`. + +For this scope, let's create a file `.maven-settings.xml` and copy the following text in it. + +```xml + + + + central + ${repoUser} + ${repoKey} + + + +``` + +**Note**: `username` and `password` will be replaced by the correct values using secret variables. + +We should remember to commit this file to our repo! + +#### Configure GitLab Continuous Integration for `simple-maven-dep` + +Now it's time we set up GitLab CI to automatically build, test and deploy our dependency! + +First of all, we should remember that we need to setup some secret variable for making the deploy happen, so let's go in the **Settings ➔ Pipelines** and add the following secret variables (replace them with your current values, of course): +- **ARTIFACTORY_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) +- **ARTIFACTORY_REPO_USER**: `gitlab` (your Artifactory username) +- **ARTIFACTORY_REPO_KEY**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory API Key) + +Now it's time to define stages in our `.gitlab-ci.yml` file: once pushed to our repo it will instruct the GitLab Runner with all the needed commands. Let's see the content of the file: @@ -50,125 +104,107 @@ test: stage: test script: - mvn test -``` -We want to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Caching the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a specific order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances caching everything that is already created in a previous step. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. - -If you're creating the file using the GitLab UI, you just have to commit directly into `master`. Otherwise, if you cloned locally your brand new project, commit and push to remote. - -Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's wait until the pipeline ends, and we should see something like the following text in the job output log. +deploy: + stage: deploy + script: + - cp .maven-settings.xml ~/.m2/settings.xml + - mvn deploy -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUsername=$ARTIFACTORY_REPO_USER -DrepoPassword=$ARTIFACTORY_REPO_KEY + only: + - master ``` -Running com.example.app.AppTest -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.049 sec -Results : +We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Caching the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances by caching everything that has been already created in a previous stage. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. + +Deployment copies the configuration file in the proper location, and then deploys to Artifactory as defined by the secret variables we set up earlier. The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. -Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 +Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's go to the **Pipelines** tab and see what happens. +If we've no errors, we can see some text like this at the end of the `deploy` job output log: +``` [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ -[INFO] Total time: 13.165 s -[INFO] Finished at: 2017-06-26T14:26:43Z -[INFO] Final Memory: 17M/147M -[INFO] ------------------------------------------------------------------------ -Creating cache default... -Created cache -Job succeeded +[INFO] Total time: 1.983 s + ``` -**Note**: the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log. +**Note**: the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log. -## Set up Artifactory as the deployment repo - -### Configure POM file +Wow! We did it! Checking in Artifactory will confirm that we've a new artifact available in the `libs-release-local` repo. -Next step is to setup our project to use Artifactory as its repository for artifacts deployment: in order to complete this, we need access to the Artifactory instance. -So, first of all let's select the `libs-release-local` repository in the `Set Me Up` section, and copy to clipboard the configuration snipped marked as `Deploy`. This is the "address" of our repo, and it is needed by Maven to push artifacts during the `deploy` stage. -Now let's go back to our project and edit the pom.xml file: we have to add the snipped we just copied from Artifactory into the project section, so we can paste it after the dependencies. -The final POM will look like this: - -```xml - - 4.0.0 - com.example.app - maven-example-app - jar - 1.0 - maven-example-app - http://maven.apache.org - - - junit - junit - 3.8.1 - test - - - - - central - 0072a36394cd-releases - http://localhost:8081/artifactory/libs-release-local - - - -``` +## Create the main Maven application + +#### Prepare the application + +Now that we've our dependency available on Artifactory, we want to use it! + +Let's create another application by cloning the one we can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. +If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. + +Since Maven doesn't know how to resolve the dependency, we need to modify the configuration. +Let's go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. In the **Dependency Declaration** section of the main panel we can copy the configuration snippet: -### Configure credentials for the repo - -One last step is required to actully deploy artifacts to Artifactory: we need to configure credentials for our repo, and best practices want us to create an API key for this task, so we don't have to expose our account password. -Let's go back to Artifactory, edit the account settings and generate a new API key. For security reasons, we don't want to expose directly this key into the `.gitlab-ci.yml, so we're going to create secret variables REPO_USERNAME and REPO_PASSWORD containing the username and the key in our GitLab project settings. - -[screenshot of secret variables window] - -We must now include these credentials in the `~/.m2/settings.xml` file, so let's create a file named `.maven-settings.xml` in our project folder with the following content: - ```xml - - - - ${REPO_USERNAME} - ${REPO_PASSWORD} - central - - - + + com.example.dep + simple-maven-dep + 1.0 + ``` -Note that `id` must have the same value as the related `id` field of the `repository` section in `pom.xml`. - -## Configure automatic deployment - -Time to change `.gitlab-ci.yml` and add the deploy stage! Maven has the perfect command for that, but it requires `settings.xml` to be in the correct folder, so we need to move it before executing `mvn deploy` command. - -The complete file is now this: - +Let's just copy this in the `dependencies` section of our `pom.xml` file. + +#### Configure the Artifactory repository location + +At this point we defined our dependency for the application, but we still miss where we can find the required files. +We need to create a `.maven-settings.xml` file as we did for our dependency project, and move it to the proper location for each job. + +Here is how we can get the content of the file directly from Artifactory: +1. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel +2. click on **Generate Maven Settings** +3. click on **Generate Settings** +3. copy to clipboard the configuration file +4. save the file as `.maven-settings.xml` in your repo, removing the `servers` section entirely + +Now we're ready to use our Artifactory repository to resolve dependencies and use `simple-maven-dep` in our application! + +#### Configure GitLab Continuous Integration for `simple-maven-app` + +We need a last step to have everything in place: configure `.gitlab-ci.yml`. + +We want to build, test and run our awesome application, and see if we can get the greeting we expect! + +So let's add the `.gitlab-ci.yml` to our repo: + ```yaml image: maven:latest - + +stages: + - build + - test + - run + cache: paths: - target/ - + build: stage: build script: - mvn compile - + test: stage: test script: - mvn test - -deploy: - stage: deploy + +run: + stage: run script: - cp .maven-settings.xml ~/.m2/settings.xml - - mvn deploy - only: - - master + - mvn package + - mvn exec:java -Dexec.mainClass="com.example.app.App" ``` -We're ready to go! Every merge (or push) to master will now trigger the deployment to our Artifactory repository! \ No newline at end of file + +And that's it! In the `run` job output log we will find a friendly hello to GitLab! \ No newline at end of file -- cgit v1.2.1 From 43f48bc27b8fa5f8ed2465ce401df965a3529ea9 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Wed, 28 Jun 2017 12:50:19 +0000 Subject: Update index.md --- .../index.md | 28 ++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 4c11257e1eb..49145da5d1d 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -5,6 +5,18 @@ ## Index +- [Introduction](#introduction) + +- [Create the simple Maven dependency](#create-the-simple-maven-dependency) + - [Get the sources](#get-the-sources) + - [Configure Artifactory deployment](#configure-artifactory-deployment) + - [Configure GitLab Continuous Integration for `simple-maven-dep`](#configure-gitlab-continuous-integration-for-simple-maven-dep) + +- [Create the main Maven application](#create-the-main-maven-application) + - [Prepare the application](#prepare-the-application) + - [Configure the Artifactory repository location](#configure-the-artifactory-repository-location) + - [Configure GitLab Continuous Integration for `simple-maven-app`](#configure-gitlab-continuous-integration-for-simple-maven-app) + ## Introduction In this article, we're going to see how we can leverage the power of [GitLab Continuous Integration](https://about.gitlab.com/features/gitlab-ci-cd/) to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/) and then use it from another Maven application as a dependency. @@ -23,7 +35,7 @@ We also assume that an Artifactory instance is available and reachable from the First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. This will be our dependency we want to package and deploy to Artifactory, in order to be available to other projects. For this article we'll use a Maven app that can be cloned at `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, so let's login into our GitLab account and create a new project -with **Import project from ➔ Repo by URL**. +with **Import project from ➔ Repo by URL**. Let's make it `public` so anyone can contribute! This application is nothing more than a basic class with a stub for a JUnit based test suite. It exposes a method called `hello` that accepts a string as input, and prints an hello message on the screen. @@ -38,6 +50,7 @@ The application is ready to use, but we need some additional steps for deploying 1. login to Artifactory with your user's credentials 2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel 3. copy to clipboard the configuration snippet under the **Deploy** paragraph +4. change the `url` value in order to have it configurable via secret variables The snippet should look like this: @@ -46,11 +59,10 @@ The snippet should look like this: central 83d43b5afeb5-releases - ${repoURL}/libs-release-local + ${repoUrl}/libs-release-local ``` -**Note**: `url` has been added in order to make it configurable but could be kept static, we'll see later how to use secret variables for this. Now let's copy the snippet in the `pom.xml` file for our project, just after the `dependencies` section. Easy! @@ -73,7 +85,7 @@ For this scope, let's create a file `.maven-settings.xml` and copy the following **Note**: `username` and `password` will be replaced by the correct values using secret variables. -We should remember to commit this file to our repo! +We should remember to commit all the changes to our repo! #### Configure GitLab Continuous Integration for `simple-maven-dep` @@ -109,7 +121,7 @@ deploy: stage: deploy script: - cp .maven-settings.xml ~/.m2/settings.xml - - mvn deploy -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUsername=$ARTIFACTORY_REPO_USER -DrepoPassword=$ARTIFACTORY_REPO_KEY + - mvn deploy -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUser=$ARTIFACTORY_REPO_USER -DrepoKey=$ARTIFACTORY_REPO_KEY only: - master ``` @@ -139,7 +151,7 @@ Wow! We did it! Checking in Artifactory will confirm that we've a new artifact a Now that we've our dependency available on Artifactory, we want to use it! -Let's create another application by cloning the one we can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. +Let's create another application by cloning the one we can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`, and make it `public` too! If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. Since Maven doesn't know how to resolve the dependency, we need to modify the configuration. @@ -189,6 +201,9 @@ cache: paths: - target/ +before_script: + - cp .maven-settings.xml ~/.m2/settings.xml + build: stage: build script: @@ -202,7 +217,6 @@ test: run: stage: run script: - - cp .maven-settings.xml ~/.m2/settings.xml - mvn package - mvn exec:java -Dexec.mainClass="com.example.app.App" ``` -- cgit v1.2.1 From 10c2ae8c5a884de6cb7339e0a7af70cb08e35268 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Wed, 28 Jun 2017 23:41:12 +0000 Subject: Update index.md --- .../index.md | 38 +++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 49145da5d1d..ddb9ee6c9b8 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -66,9 +66,9 @@ The snippet should look like this: Now let's copy the snippet in the `pom.xml` file for our project, just after the `dependencies` section. Easy! -Another step we need to do before we can deploy our dependency to Artifactory is to configure authentication data. It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. Since we want to use GitLab Runner to automatically deploy the application, we should create the file in our project home and then move it to the proper location with a specific command in the `.gitlab-ci.yml`. +Another step we need to do before we can deploy our dependency to Artifactory is to configure authentication data. It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. Since we want to use GitLab Runner to automatically deploy the application, we should create the file in our project home and set a command line parameter in `.gitlab-ci.yml` to use our location instead of the default one. -For this scope, let's create a file `.maven-settings.xml` and copy the following text in it. +For this scope, let's create a folder called `.m2` in the root of our repo. Inside we must create a file named `settings.xml` and copy the following text in it. ```xml Date: Wed, 28 Jun 2017 23:47:10 +0000 Subject: Update index.md --- .../index.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index ddb9ee6c9b8..8f67b56385d 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -56,11 +56,11 @@ The snippet should look like this: ```xml - - central - 83d43b5afeb5-releases - ${repoUrl}/libs-release-local - + + central + 83d43b5afeb5-releases + ${repoUrl}/libs-release-local + ``` @@ -132,7 +132,7 @@ deploy: We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. Caching the `.m2` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances by caching everything that has been already created in a previous stage. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. -Deployment copies the configuration file in the proper location, and then deploys to Artifactory as defined by the secret variables we set up earlier. The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. +Deploy to Artifactory is done as defined by the secret variables we set up earlier. The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's go to the **Pipelines** tab and see what happens. If we've no errors, we can see some text like this at the end of the `deploy` job output log: @@ -145,7 +145,7 @@ If we've no errors, we can see some text like this at the end of the `deploy` jo ``` -**Note**: the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log. +**Note**: the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log the first time you run it. Wow! We did it! Checking in Artifactory will confirm that we've a new artifact available in the `libs-release-local` repo. @@ -163,9 +163,9 @@ Let's go back to Artifactory, and browse the `libs-release-local` repository sel ```xml - com.example.dep - simple-maven-dep - 1.0 + com.example.dep + simple-maven-dep + 1.0 ``` -- cgit v1.2.1 From 5474b4e0ce643f316d146dfa57f28a0dc874033e Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 29 Jun 2017 00:01:25 +0000 Subject: Update index.md --- .../index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 8f67b56385d..5f326588372 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -109,7 +109,7 @@ variables: cache: paths: - - .m2/ + - .m2/repository/ - target/ build: @@ -130,7 +130,7 @@ deploy: - master ``` -We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. Caching the `.m2` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances by caching everything that has been already created in a previous stage. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. +We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. Caching the `.m2/repository` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances by caching everything that has been already created in a previous stage. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. Deploy to Artifactory is done as defined by the secret variables we set up earlier. The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. @@ -207,7 +207,7 @@ variables: cache: paths: - - .m2/ + - .m2/repository/ - target/ build: -- cgit v1.2.1 From 1697e2c485b8d1e85df8e5723793a6316272ec15 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 29 Jun 2017 07:05:59 +0000 Subject: Update index.md --- .../index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 5f326588372..afcce2dfe23 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -34,7 +34,7 @@ We also assume that an Artifactory instance is available and reachable from the First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. This will be our dependency we want to package and deploy to Artifactory, in order to be available to other projects. -For this article we'll use a Maven app that can be cloned at `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, so let's login into our GitLab account and create a new project +For this article we'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, so let's login into our GitLab account and create a new project with **Import project from ➔ Repo by URL**. Let's make it `public` so anyone can contribute! This application is nothing more than a basic class with a stub for a JUnit based test suite. @@ -125,7 +125,7 @@ test: deploy: stage: deploy script: - - mvn deploy $fMAVEN_CLI_OPTS -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUser=$ARTIFACTORY_REPO_USER -DrepoKey=$ARTIFACTORY_REPO_KEY + - mvn deploy $MAVEN_CLI_OPTS -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUser=$ARTIFACTORY_REPO_USER -DrepoKey=$ARTIFACTORY_REPO_KEY only: - master ``` @@ -181,7 +181,7 @@ Here is how we can get the content of the file directly from Artifactory: 2. click on **Generate Maven Settings** 3. click on **Generate Settings** 3. copy to clipboard the configuration file -4. save the file as `.m2/settings.xml` in your repo, removing the `servers` section entirely +4. save the file as `.m2/settings.xml` in your repo Now we're ready to use our Artifactory repository to resolve dependencies and use `simple-maven-dep` in our application! -- cgit v1.2.1 From ecd377cd3531bb925bfe26af131e224d3fdc3fea Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Mon, 3 Jul 2017 10:38:37 +0000 Subject: Update index.md --- .../index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index afcce2dfe23..142ab373a73 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -59,7 +59,7 @@ The snippet should look like this: central 83d43b5afeb5-releases - ${repoUrl}/libs-release-local + ${env.MAVEN_REPO_URL}/libs-release-local ``` @@ -76,8 +76,8 @@ For this scope, let's create a folder called `.m2` in the root of our repo. Insi central - ${repoUser} - ${repoKey} + ${env.MAVEN_REPO_USER} + ${env.MAVEN_REPO_KEY} @@ -92,9 +92,9 @@ We should remember to commit all the changes to our repo! Now it's time we set up GitLab CI to automatically build, test and deploy our dependency! First of all, we should remember that we need to setup some secret variable for making the deploy happen, so let's go in the **Settings ➔ Pipelines** and add the following secret variables (replace them with your current values, of course): -- **ARTIFACTORY_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) -- **ARTIFACTORY_REPO_USER**: `gitlab` (your Artifactory username) -- **ARTIFACTORY_REPO_KEY**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory API Key) +- **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) +- **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) +- **MAVEN_REPO_KEY**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory API Key) Now it's time to define stages in our `.gitlab-ci.yml` file: once pushed to our repo it will instruct the GitLab Runner with all the needed commands. @@ -104,7 +104,7 @@ Let's see the content of the file: image: maven:latest variables: - MAVEN_CLI_OPTS: "-s .m2/settings.xml" + MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" cache: @@ -125,7 +125,7 @@ test: deploy: stage: deploy script: - - mvn deploy $MAVEN_CLI_OPTS -DrepoUrl=$ARTIFACTORY_REPO_URL -DrepoUser=$ARTIFACTORY_REPO_USER -DrepoKey=$ARTIFACTORY_REPO_KEY + - mvn $MAVEN_CLI_OPTS deploy only: - master ``` @@ -202,7 +202,7 @@ stages: - run variables: - MAVEN_CLI_OPTS: "-s .m2/settings.xml" + MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" cache: -- cgit v1.2.1 From 41b9a08cebd8b63a0b5441244af921e631e79a51 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Fri, 21 Jul 2017 07:01:59 +0000 Subject: Add Conclusion Fix styling --- .../index.md | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 142ab373a73..b9472602e7b 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -17,6 +17,8 @@ - [Configure the Artifactory repository location](#configure-the-artifactory-repository-location) - [Configure GitLab Continuous Integration for `simple-maven-app`](#configure-gitlab-continuous-integration-for-simple-maven-app) +- [Conclusion](#conclusion) + ## Introduction In this article, we're going to see how we can leverage the power of [GitLab Continuous Integration](https://about.gitlab.com/features/gitlab-ci-cd/) to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/) and then use it from another Maven application as a dependency. @@ -83,7 +85,8 @@ For this scope, let's create a folder called `.m2` in the root of our repo. Insi ``` -**Note**: `username` and `password` will be replaced by the correct values using secret variables. +>**Note**: +`username` and `password` will be replaced by the correct values using secret variables. We should remember to commit all the changes to our repo! @@ -91,7 +94,8 @@ We should remember to commit all the changes to our repo! Now it's time we set up GitLab CI to automatically build, test and deploy our dependency! -First of all, we should remember that we need to setup some secret variable for making the deploy happen, so let's go in the **Settings ➔ Pipelines** and add the following secret variables (replace them with your current values, of course): +First of all, we should remember that we need to setup some secret variable for making the deploy happen, so let's go in the **Settings ➔ Pipelines** +and add the following secret variables (replace them with your current values, of course): - **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) - **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) - **MAVEN_REPO_KEY**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory API Key) @@ -130,9 +134,15 @@ deploy: - master ``` -We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. Caching the `.m2/repository` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, but we want to improve performances by caching everything that has been already created in a previous stage. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. +We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. +Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. +Caching the `.m2/repository` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, +is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, +but we want to improve performances by caching everything that has been already created in a previous stage. +Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. -Deploy to Artifactory is done as defined by the secret variables we set up earlier. The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. +Deploy to Artifactory is done as defined by the secret variables we set up earlier. +The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's go to the **Pipelines** tab and see what happens. If we've no errors, we can see some text like this at the end of the `deploy` job output log: @@ -145,7 +155,8 @@ If we've no errors, we can see some text like this at the end of the `deploy` jo ``` -**Note**: the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log the first time you run it. +>**Note**: +the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log the first time you run it. Wow! We did it! Checking in Artifactory will confirm that we've a new artifact available in the `libs-release-local` repo. @@ -159,7 +170,8 @@ Let's create another application by cloning the one we can find at `https://gitl If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. Since Maven doesn't know how to resolve the dependency, we need to modify the configuration. -Let's go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. In the **Dependency Declaration** section of the main panel we can copy the configuration snippet: +Let's go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. +In the **Dependency Declaration** section of the main panel we can copy the configuration snippet: ```xml @@ -227,4 +239,13 @@ run: - mvn $MAVEN_CLI_OPTS exec:java -Dexec.mainClass="com.example.app.App" ``` -And that's it! In the `run` job output log we will find a friendly hello to GitLab! \ No newline at end of file +And that's it! In the `run` job output log we will find a friendly hello to GitLab! + +## Conclusion + +In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume our artifacts. + +A similar approach could be used to interact with any other Maven compatible Binary Repository Manager. +You can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. + +Enjoy GitLab CI with all your Maven projects! \ No newline at end of file -- cgit v1.2.1 From 829a73af1ff0d866633d22ddea673bbf74bb4e30 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Tue, 25 Jul 2017 00:38:19 +0000 Subject: Update password options --- .../index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index b9472602e7b..784676ae8d2 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -79,7 +79,7 @@ For this scope, let's create a folder called `.m2` in the root of our repo. Insi central ${env.MAVEN_REPO_USER} - ${env.MAVEN_REPO_KEY} + ${env.MAVEN_REPO_PASS} @@ -98,7 +98,7 @@ First of all, we should remember that we need to setup some secret variable for and add the following secret variables (replace them with your current values, of course): - **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) - **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) -- **MAVEN_REPO_KEY**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory API Key) +- **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password) Now it's time to define stages in our `.gitlab-ci.yml` file: once pushed to our repo it will instruct the GitLab Runner with all the needed commands. -- cgit v1.2.1 From 135e37db6a20b4ee97d7529c5c2636045373812b Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 01:06:19 +0000 Subject: Update index.md --- .../index.md | 126 +++++++++------------ 1 file changed, 56 insertions(+), 70 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 784676ae8d2..d2061279646 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -1,55 +1,43 @@ +# How to deploy Maven projects to Artifactory with GitLab CI/CD + > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || > **Publication date:** AAAA/MM/DD -## Index - -- [Introduction](#introduction) - -- [Create the simple Maven dependency](#create-the-simple-maven-dependency) - - [Get the sources](#get-the-sources) - - [Configure Artifactory deployment](#configure-artifactory-deployment) - - [Configure GitLab Continuous Integration for `simple-maven-dep`](#configure-gitlab-continuous-integration-for-simple-maven-dep) - -- [Create the main Maven application](#create-the-main-maven-application) - - [Prepare the application](#prepare-the-application) - - [Configure the Artifactory repository location](#configure-the-artifactory-repository-location) - - [Configure GitLab Continuous Integration for `simple-maven-app`](#configure-gitlab-continuous-integration-for-simple-maven-app) - -- [Conclusion](#conclusion) - ## Introduction -In this article, we're going to see how we can leverage the power of [GitLab Continuous Integration](https://about.gitlab.com/features/gitlab-ci-cd/) to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/) and then use it from another Maven application as a dependency. +In this article, we will show how you can leverage the power of [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) +to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/), and then use it from another Maven application as a dependency. -We're going to create two different projects: +You'll create two different projects: - `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) - `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) -We assume that we already have a GitLab account on [GitLab.com](https://gitlab.com/), and that we know the basic usage of CI. -We also assume that an Artifactory instance is available and reachable from the Internet, and that we've valid credentials to deploy on it. +We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of GitLab CI/CD. +We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it. ## Create the simple Maven dependency -#### Get the sources +### Get the sources -First of all, we need an application to work with: in this specific case we're going to make it simple, but it could be any Maven application. This will be our dependency we want to package and deploy to Artifactory, in order to be available to other projects. +First of all, you need an application to work with: in this specific it is a simple one, but it could be any Maven application. +This will be the dependency you want to package and deploy to Artifactory, in order to be available to other projects. -For this article we'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, so let's login into our GitLab account and create a new project -with **Import project from ➔ Repo by URL**. Let's make it `public` so anyone can contribute! +For this article you'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, +so log in to your GitLab account and create a new project with **Import project from ➔ Repo by URL**. This application is nothing more than a basic class with a stub for a JUnit based test suite. -It exposes a method called `hello` that accepts a string as input, and prints an hello message on the screen. +It exposes a method called `hello` that accepts a string as input, and prints a hello message on the screen. -The project structure is really simple, and we're mainly interested in these two resources: +The project structure is really simple, and you should consider these two resources: - `pom.xml`: project object model (POM) configuration file - `src/main/java/com/example/dep/Dep.java`: source of our application -#### Configure Artifactory deployment +### Configure Artifactory deployment -The application is ready to use, but we need some additional steps for deploying it to Artifactory: -1. login to Artifactory with your user's credentials +The application is ready to use, but you need some additional steps to deploy it to Artifactory: +1. log in to Artifactory with your user's credentials 2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel 3. copy to clipboard the configuration snippet under the **Deploy** paragraph 4. change the `url` value in order to have it configurable via secret variables @@ -66,11 +54,14 @@ The snippet should look like this: ``` -Now let's copy the snippet in the `pom.xml` file for our project, just after the `dependencies` section. Easy! +Now copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section. Easy! -Another step we need to do before we can deploy our dependency to Artifactory is to configure authentication data. It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. Since we want to use GitLab Runner to automatically deploy the application, we should create the file in our project home and set a command line parameter in `.gitlab-ci.yml` to use our location instead of the default one. +Another step you need to do before you can deploy the dependency to Artifactory is to configure authentication data. +It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. +Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home +and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one. -For this scope, let's create a folder called `.m2` in the root of our repo. Inside we must create a file named `settings.xml` and copy the following text in it. +For this scope, create a folder called `.m2` in the root of the repo. You must create a file named `settings.xml` there, and copy the following text into it. ```xml **Note**: `username` and `password` will be replaced by the correct values using secret variables. -We should remember to commit all the changes to our repo! +Remember to commit all the changes to the repo! -#### Configure GitLab Continuous Integration for `simple-maven-dep` +### Configure GitLab CI/CD for `simple-maven-dep` -Now it's time we set up GitLab CI to automatically build, test and deploy our dependency! +Now it's time we set up GitLab CI/CD to automatically build, test and deploy the dependency! -First of all, we should remember that we need to setup some secret variable for making the deploy happen, so let's go in the **Settings ➔ Pipelines** +First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > Pipelines** page and add the following secret variables (replace them with your current values, of course): - **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) - **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) - **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password) -Now it's time to define stages in our `.gitlab-ci.yml` file: once pushed to our repo it will instruct the GitLab Runner with all the needed commands. - -Let's see the content of the file: +Now it's time to define jobs in `.gitlab-ci.yml` file: once pushed to the repo it will instruct the GitLab Runner with all the needed commands. ```yaml image: maven:latest @@ -134,18 +123,17 @@ deploy: - master ``` -We're going to use the latest Docker image publicly available for Maven, which already contains everything we need to perform our tasks. -Environment variables are set to instruct Maven to use the homedir of our repo instead of the user's home. -Caching the `.m2/repository` folder, where all the Maven files are stored, and the `target` folder, that is the location where our application will be created, -is useful in order to speed up the process: Maven runs all its phases in a sequential order, so executing `mvn test` will automatically run `mvn compile` if needed, -but we want to improve performances by caching everything that has been already created in a previous stage. +It uses the latest Docker image for Maven, which already contains everything you need to perform all the tasks. +Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home. +Caching the .m2/repository folder (where all the Maven files are stored), and the target folder (where our application will be created), will be useful for speeding up the process +by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. Deploy to Artifactory is done as defined by the secret variables we set up earlier. -The deployment occurs only if we're pushing or merging to `master` branch, so development versions are tested but not published. +The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published. -Done! We've now our changes in the GitLab repo, and a pipeline has already been started for this commit. Let's go to the **Pipelines** tab and see what happens. -If we've no errors, we can see some text like this at the end of the `deploy` job output log: +Done! Now you have all the changes in the GitLab repo, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening. +If the deployment has been successful, the deploy job log will output: ``` [INFO] ------------------------------------------------------------------------ @@ -156,22 +144,22 @@ If we've no errors, we can see some text like this at the end of the `deploy` jo ``` >**Note**: -the `mvn` command downloads a lot of files from the Internet, so you'll see a lot of extra activity in the log the first time you run it. +the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log the first time you run it. -Wow! We did it! Checking in Artifactory will confirm that we've a new artifact available in the `libs-release-local` repo. +Yay! You did it! Checking in Artifactory will confirm that you have a new artifact available in the `libs-release-local` repo. ## Create the main Maven application -#### Prepare the application +### Prepare the application -Now that we've our dependency available on Artifactory, we want to use it! +Now that you have the dependency available on Artifactory, you want to use it! -Let's create another application by cloning the one we can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`, and make it `public` too! +Create another application by cloning the one you can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. -Since Maven doesn't know how to resolve the dependency, we need to modify the configuration. -Let's go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. -In the **Dependency Declaration** section of the main panel we can copy the configuration snippet: +Since Maven doesn't know how to resolve the dependency, you need to modify the configuration. +Go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. +In the **Dependency Declaration** section of the main panel you can copy the configuration snippet: ```xml @@ -181,29 +169,29 @@ In the **Dependency Declaration** section of the main panel we can copy the conf ``` -Let's just copy this in the `dependencies` section of our `pom.xml` file. +Copy this in the `dependencies` section of the `pom.xml` file. -#### Configure the Artifactory repository location +### Configure the Artifactory repository location -At this point we defined our dependency for the application, but we still miss where we can find the required files. -We need to create a `.m2/settings.xml` file as we did for our dependency project, and let Maven know the location using environment variables. +At this point you defined the dependency for the application, but you still miss where you can find the required files. +You need to create a `.m2/settings.xml` file as you did for the dependency project, and let Maven know the location using environment variables. -Here is how we can get the content of the file directly from Artifactory: +Here is how you can get the content of the file directly from Artifactory: 1. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel 2. click on **Generate Maven Settings** 3. click on **Generate Settings** 3. copy to clipboard the configuration file 4. save the file as `.m2/settings.xml` in your repo -Now we're ready to use our Artifactory repository to resolve dependencies and use `simple-maven-dep` in our application! +Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your application! -#### Configure GitLab Continuous Integration for `simple-maven-app` +### Configure GitLab CI/CD for `simple-maven-app` -We need a last step to have everything in place: configure `.gitlab-ci.yml`. +You need a last step to have everything in place: configure `.gitlab-ci.yml`. -We want to build, test and run our awesome application, and see if we can get the greeting we expect! +You want to build, test and run your awesome application, and see if you can get the greeting as expected! -So let's add the `.gitlab-ci.yml` to our repo: +Add the `.gitlab-ci.yml` to the repo: ```yaml image: maven:latest @@ -239,13 +227,11 @@ run: - mvn $MAVEN_CLI_OPTS exec:java -Dexec.mainClass="com.example.app.App" ``` -And that's it! In the `run` job output log we will find a friendly hello to GitLab! +And that's it! In the `run` job output log you will find a friendly hello to GitLab! ## Conclusion -In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume our artifacts. +In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume artifacts. A similar approach could be used to interact with any other Maven compatible Binary Repository Manager. -You can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. - -Enjoy GitLab CI with all your Maven projects! \ No newline at end of file +Obviously, you can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. \ No newline at end of file -- cgit v1.2.1 From ed5445388de13f1d126fec14cc0a9ea9ae03b397 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 01:23:11 +0000 Subject: Update index.md --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index d2061279646..2dba8688a24 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -129,7 +129,7 @@ Caching the .m2/repository folder (where all the Maven files are stored), and th by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. -Deploy to Artifactory is done as defined by the secret variables we set up earlier. +Deploy to Artifactory is done as defined by the secret variables we have just set up. The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published. Done! Now you have all the changes in the GitLab repo, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening. -- cgit v1.2.1 From 1379f0e3826b953e8f67a427b759abb7af88df80 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 09:13:08 +0000 Subject: Update index.md --- .../index.md | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 2dba8688a24..2a8e9ea2717 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -14,7 +14,7 @@ You'll create two different projects: - `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) - `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) -We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of GitLab CI/CD. +We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and GitLab CI/CD. We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it. ## Create the simple Maven dependency @@ -41,6 +41,7 @@ The application is ready to use, but you need some additional steps to deploy it 2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel 3. copy to clipboard the configuration snippet under the **Deploy** paragraph 4. change the `url` value in order to have it configurable via secret variables +5. copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section The snippet should look like this: @@ -54,14 +55,14 @@ The snippet should look like this: ``` -Now copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section. Easy! - Another step you need to do before you can deploy the dependency to Artifactory is to configure authentication data. It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. -Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home -and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one. -For this scope, create a folder called `.m2` in the root of the repo. You must create a file named `settings.xml` there, and copy the following text into it. +Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home +and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one: +1. create a folder called `.m2` in the root of the repo +2. create a file called `settings.xml` in the `.m2` folder +3. copy the following content into `settings.xml` ```xml **Note**: `username` and `password` will be replaced by the correct values using secret variables. -Remember to commit all the changes to the repo! - ### Configure GitLab CI/CD for `simple-maven-dep` Now it's time we set up GitLab CI/CD to automatically build, test and deploy the dependency! @@ -157,9 +156,14 @@ Now that you have the dependency available on Artifactory, you want to use it! Create another application by cloning the one you can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. -Since Maven doesn't know how to resolve the dependency, you need to modify the configuration. -Go back to Artifactory, and browse the `libs-release-local` repository selecting the `simple-maven-dep-1.0.jar` file. -In the **Dependency Declaration** section of the main panel you can copy the configuration snippet: +Since Maven doesn't know how to resolve the dependency, you need to modify the configuration: +1. go back to Artifactory +2. browse the `libs-release-local` repository +3. select the `simple-maven-dep-1.0.jar` file +4. find the configuration snippet from the **Dependency Declaration** section of the main panel +5. copy the snippet in the `dependencies` section of the `pom.xml` file + +The snippet should look like this: ```xml @@ -169,8 +173,6 @@ In the **Dependency Declaration** section of the main panel you can copy the con ``` -Copy this in the `dependencies` section of the `pom.xml` file. - ### Configure the Artifactory repository location At this point you defined the dependency for the application, but you still miss where you can find the required files. -- cgit v1.2.1 From 4a9dd1d0d18cdb5cdb8b7f45d467554efd7e514b Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 09:44:40 +0000 Subject: Update index.md --- .../index.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 2a8e9ea2717..9622b4b0761 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -14,7 +14,7 @@ You'll create two different projects: - `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) - `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) -We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and GitLab CI/CD. +We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/). We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it. ## Create the simple Maven dependency @@ -82,7 +82,10 @@ and set a command line parameter in `.gitlab-ci.yml` to use the custom location ### Configure GitLab CI/CD for `simple-maven-dep` -Now it's time we set up GitLab CI/CD to automatically build, test and deploy the dependency! +Now it's time we set up [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and deploy the dependency! + +[GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs +that will be executed by the configured GitLab Runners. You can read more about this file in the [GitLab Documentation](https://docs.gitlab.com/ee/ci/yaml/). First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > Pipelines** page and add the following secret variables (replace them with your current values, of course): @@ -189,11 +192,12 @@ Now you are ready to use the Artifactory repository to resolve dependencies and ### Configure GitLab CI/CD for `simple-maven-app` -You need a last step to have everything in place: configure `.gitlab-ci.yml`. +You need a last step to have everything in place: configure the `.gitlab-ci.yml` file for this project, as you already did for `simple-maven-dep`. -You want to build, test and run your awesome application, and see if you can get the greeting as expected! +You want to leverage [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and run your awesome application, +and see if you can get the greeting as expected! -Add the `.gitlab-ci.yml` to the repo: +All you need to do is to add the following `.gitlab-ci.yml` to the repo: ```yaml image: maven:latest @@ -229,6 +233,9 @@ run: - mvn $MAVEN_CLI_OPTS exec:java -Dexec.mainClass="com.example.app.App" ``` +It is very similar to the configuration used for `simple-maven-dep`, but instead of the `deploy` job there is a `run` job. +Probably something that you don't want to use in real projects, but here it is useful to see the application automatically running. + And that's it! In the `run` job output log you will find a friendly hello to GitLab! ## Conclusion -- cgit v1.2.1 From f38e0d5be0df51870d4a619462dfde53d8afb60e Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 09:52:12 +0000 Subject: Update index.md --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 9622b4b0761..c029cb65956 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -234,7 +234,7 @@ run: ``` It is very similar to the configuration used for `simple-maven-dep`, but instead of the `deploy` job there is a `run` job. -Probably something that you don't want to use in real projects, but here it is useful to see the application automatically running. +Probably something that you don't want to use in real projects, but here it is useful to see the application executed automatically. And that's it! In the `run` job output log you will find a friendly hello to GitLab! -- cgit v1.2.1 From c90f3009c67078b97a41b716e31c46376ee3e47e Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 10:03:16 +0000 Subject: Update index.md --- .../index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index c029cb65956..9b15159e08c 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -125,11 +125,12 @@ deploy: - master ``` -It uses the latest Docker image for Maven, which already contains everything you need to perform all the tasks. -Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home. -Caching the .m2/repository folder (where all the Maven files are stored), and the target folder (where our application will be created), will be useful for speeding up the process +GitLab Runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project, +in order to run the jobs. +Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home when searching for configuration and dependencies. +Caching the `.m2/repository folder` (where all the Maven files are stored), and the `target` folder (where our application will be created), is useful for speeding up the process by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. -Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the repository. +Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the application. Deploy to Artifactory is done as defined by the secret variables we have just set up. The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published. -- cgit v1.2.1 From 9e71d42761f1164bc90de041ed6813248fa1ec7d Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 3 Aug 2017 10:10:14 +0000 Subject: Update index.md --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md index 9b15159e08c..5d9c8b17053 100644 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || -> **Publication date:** AAAA/MM/DD +> **Publication date:** 2017/08/03 ## Introduction -- cgit v1.2.1 From 46cb252698c81b7f50475dcfb38246d0229245e6 Mon Sep 17 00:00:00 2001 From: Crt Mori Date: Fri, 11 Aug 2017 19:31:33 +0000 Subject: Doc numerous undo possibilities in git --- .../img/branching.png | Bin 0 -> 26245 bytes .../img/rebase_reset.png | Bin 0 -> 43609 bytes .../img/revert.png | Bin 0 -> 28112 bytes .../numerous_undo_possibilities_in_git/index.md | 511 +++++++++++++++++++++ 4 files changed, 511 insertions(+) create mode 100644 doc/articles/numerous_undo_possibilities_in_git/img/branching.png create mode 100644 doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png create mode 100644 doc/articles/numerous_undo_possibilities_in_git/img/revert.png create mode 100644 doc/articles/numerous_undo_possibilities_in_git/index.md (limited to 'doc/articles') diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/branching.png b/doc/articles/numerous_undo_possibilities_in_git/img/branching.png new file mode 100644 index 00000000000..9a80c211c99 Binary files /dev/null and b/doc/articles/numerous_undo_possibilities_in_git/img/branching.png differ diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png b/doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png new file mode 100644 index 00000000000..ac7ea9ecddc Binary files /dev/null and b/doc/articles/numerous_undo_possibilities_in_git/img/rebase_reset.png differ diff --git a/doc/articles/numerous_undo_possibilities_in_git/img/revert.png b/doc/articles/numerous_undo_possibilities_in_git/img/revert.png new file mode 100644 index 00000000000..13b3a35ca45 Binary files /dev/null and b/doc/articles/numerous_undo_possibilities_in_git/img/revert.png differ diff --git a/doc/articles/numerous_undo_possibilities_in_git/index.md b/doc/articles/numerous_undo_possibilities_in_git/index.md new file mode 100644 index 00000000000..612e2b88190 --- /dev/null +++ b/doc/articles/numerous_undo_possibilities_in_git/index.md @@ -0,0 +1,511 @@ +# Numerous undo possibilities in Git + +> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || +> **Level:** intermediary || +> **Author:** [Crt Mori](https://gitlab.com/Letme) || +> **Publication date:** 2017/08/04 + +## Introduction + +In this tutorial, we will show you different ways of undoing in Git, for which +we will assume you have a basic working knowledge of. Check GitLab's +[Git documentation](../../topics/git/index.md#git-documentation) for reference. +Also, we will only provide some general info of the commands, which is enough +to get you started for the easy cases/examples, but you will have to read the +command manual for anything more advanced. + +We will explain a few different techniques to undo your changes based on the stage +of the change in your current development. Also, keep in mind that [nothing in +Git is really deleted.][git-autoclean-ref] +This means that until Git automatically cleans detached commits (which cannot be +accessed by branch or tag) it will be possible to view them with `git reflog` command +and access them with direct commit-id. You can read more about [redo in below section](#redoing-the-undo). + +This guide is organized depending on the [stage of development][git-basics] +where you want to undo your changes from and if they were shared with other developers +or not. Because Git is tracking changes a created or edited file is in the unstaged state +(if created it is untracked by Git). After you add it to a repository (`git add`) you put +a file into the **staged** state, which is then committed (`git commit`) to your +local repository. After that, file can be shared with other developers (`git push`). +Here's what we'll cover in this tutorial: + + - [Undo local changes](#undo-local-changes) which were not pushed to remote repository + + - Before you commit, in both unstaged and staged state + - After you committed + + - Undo changes after they are pushed to remote repository + + - [Without history modification](#undo-remote-changes-without-changing-history) (preferred way) + - [With history modification](#undo-remote-changes-with-modifying-history) (requires + coordination with team and force pushes). + + - [Usecases when modifying history is generally acceptable](#where-modifying-history-is-generally-acceptable) + - [How to modify history](#how-modifying-history-is-done) + - [How to remove sensitive information from repository](#deleting-sensitive-information-from-commits) + + +### Branching strategy + +[Git][git-official] is a de-centralized version control system, which means that beside regular +versioning of the whole repository, it has possibilities to exchange changes +with other repositories. To avoid chaos with +[multiple sources of truth][git-distributed], various +development workflows have to be followed, and it depends on your internal +workflow how certain changes or commits can be undone or changed. +[GitLab Flow][gitlab-flow] provides a good +balance between developers clashing with each other while +developing the same feature and cooperating seamlessly, but it does not enable +joined development of the same feature by multiple developers by default. +When multiple developers develop the same feature on the same branch, clashing +with every synchronization is unavoidable, but a proper or chosen Git Workflow will +prevent that anything is lost or out of sync when feature is complete. You can also +read through this blog post on [Git Tips & Tricks][gitlab-git-tips-n-tricks] +to learn how to easily **do** things in Git. + + +## Undo local changes + +Until you push your changes to any remote repository, they will only affect you. +That broadens your options on how to handle undoing them. Still, local changes +can be on various stages and each stage has a different approach on how to tackle them. + + +### Unstaged local changes (before you commit) + +When a change is made, but it is not added to the staged tree, Git itself +proposes a solution to discard changes to certain file. + +Suppose you edited a file to change the content using your favorite editor: + +``` +vim +``` + +Since you did not `git add ` to staging, it should be under unstaged files (or +untracked if file was created). You can confirm that with: + +```shell +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +Changes not staged for commit: + (use "git add ..." to update what will be committed) + (use "git checkout -- ..." to discard changes in working directory) + + modified: +no changes added to commit (use "git add" and/or "git commit -a") +``` + +At this point there are 3 options to undo the local changes you have: + + - Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes) + + ``` + git stash + ``` + + - Discarding local changes (permanently) to a file + + ``` + git checkout -- + ``` + + - Discard all local changes to all files permanently + + ``` + git reset --hard + ``` + + +Before executing `git reset --hard`, keep in mind that there is also a way to +just temporary store the changes without committing them using `git stash`. +This command resets the changes to all files, but it also saves them in case +you would like to apply them at some later time. You can read more about it in +[section below](#quickly-save-local-changes). + + +### Quickly save local changes + +You are working on a feature when a boss drops by with an urgent task. Since your +feature is not complete, but you need to swap to another branch, you can use +`git stash` to save what you had done, swap to another branch, commit, push, +test, then get back to previous feature branch, do `git stash pop` and continue +where you left. + +The example above shows that discarding all changes is not always a preferred option, +but Git provides a way to save them for later, while resetting the repository to state without +them. This is achieved by Git stashing command `git stash`, which in fact saves your +current work and runs `git reset --hard`, but it also has various +additional options like: + + - `git stash save`, which enables including temporary commit message, which will help you identify changes, among with other options + - `git stash list`, which lists all previously stashed commits (yes, there can be more) that were not `pop`ed + - `git stash pop`, which redoes previously stashed changes and removes them from stashed list + - `git stash apply`, which redoes previously stashed changes, but keeps them on stashed list + + +### Staged local changes (before you commit) + +Let's say you have added some files to staging, but you want to remove them from the +current commit, yet you want to retain those changes - just move them outside +of the staging tree. You also have an option to discard all changes with +`git reset --hard` or think about `git stash` [as described earlier.](#quickly-save-local-changes) + +Lets start the example by editing a file, with your favorite editor, to change the +content and add it to staging + +``` +vim +git add +``` + +The file is now added to staging as confirmed by `git status` command: + +```shell +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: +``` + +Now you have 4 options to undo your changes: + + - Unstage the file to current commit (HEAD) + + ``` + git reset HEAD + ``` + + - Unstage everything - retain changes + + ``` + git reset + ``` + + - Discard all local changes, but save them for [later](#quickly-save-local-changes) + + ``` + git stash + ``` + + - Discard everything permanently + + ``` + git reset --hard + ``` + + +## Committed local changes + +Once you commit, your changes are recorded by the version control system. +Because you haven't pushed to your remote repository yet, your changes are +still not public (or shared with other developers). At this point, undoing +things is a lot easier, we have quite some workaround options. Once you push +your code, you'll have less options to troubleshoot your work. + + +### Without modifying history + +Through the development process some of the previously committed changes do not +fit anymore in the end solution, or are source of the bugs. Once you find the +commit which triggered bug, or once you have a faulty commit, you can simply +revert it with `git revert commit-id`. This command inverts (swaps) the additions and +deletions in that commit, so that it does not modify history. Retaining history +can be helpful in future to notice that some changes have been tried +unsuccessfully in the past. + +In our example we will assume there are commits `A`,`B`,`C`,`D`,`E` committed in this order: `A-B-C-D-E`, +and `B` is the commit you want to undo. There are many different ways to identify commit +`B` as bad, one of them is to pass a range to `git bisect` command. The provided range includes +last known good commit (we assume `A`) and first known bad commit (where bug was detected - we will assume `E`). + +``` +git bisect A..E +``` + +Bisect will provide us with commit-id of the middle commit to test, and then guide us +through simple bisection process. You can read more about it [in official Git Tools][git-debug] +In our example we will end up with commit `B`, that introduced bug/error. We have +4 options on how to remove it (or part of it) from our repository. + + - Undo (swap additions and deletions) changes introduced by commit `B`. + + ``` + git revert commit-B-id + ``` + + - Undo changes on a single file or directory from commit `B`, but retain them in the staged state + + ``` + git checkout commit-B-id + ``` + + - Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state + + ``` + git reset commit-B-id + ``` + + - There is one command we also must not forget: **creating a new branch** + from the point where changes are not applicable or where the development has hit a + dead end. For example you have done commits `A-B-C-D` on your feature-branch + and then you figure `C` and `D` are wrong. At this point you either reset to `B` + and do commit `F` (which will cause problems with pushing and if forced pushed also with other developers) + since branch now looks `A-B-F`, which clashes with what other developers have locally (you will + [change history](#with-history-modification)), or you simply checkout commit `B` create + a new branch and do commit `F`. In the last case, everyone else can still do their work while you + have your new way to get it right and merge it back in later. Alternatively, with GitLab, + you can [cherry-pick](../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit) + that commit into a new merge request. + + ![Create a new branch to avoid clashing](img/branching.png) + + ``` + git checkout commit-B-id + git checkout -b new-path-of-feature + # Create + git commit -a + ``` + + +### With history modification + +There is one command for history modification and that is `git rebase`. Command +provides interactive mode (`-i` flag) which enables you to: + + - **reword** commit messages (there is also `git commit --amend` for editing + last commit message) + - **edit** the commit content (changes introduced by commit) and message + - **squash** multiple commits into a single one, and have a custom or aggregated + commit message + - **drop** commits - simply delete them + - and few more options + +Let us check few examples. Again there are commits `A-B-C-D` where you want to +delete commit `B`. + + - Rebase the range from current commit D to A + + ``` + git rebase -i A + ``` + + - Command opens your favorite editor where you write `drop` in front of commit + `B`, but you leave default `pick` with all other commits. Save and exit the + editor to perform a rebase. Remember: if you want to cancel delete whole + file content before saving and exiting the editor + +In case you want to modify something introduced in commit `B`. + + - Rebase the range from current commit D to A + + ``` + git rebase -i A + ``` + + - Command opens your favorite text editor where you write `edit` in front of commit + `B`, but leave default `pick` with all other commits. Save and exit the editor to + perform a rebase + + - Now do your edits and commit changes + + ``` + git commit -a + ``` + +You can find some more examples in [below section where we explain how to modify +history](#how-modifying-history-is-done) + + +### Redoing the Undo + +Sometimes you realize that the changes you undid were useful and you want them +back. Well because of first paragraph you are in luck. Command `git reflog` +enables you to *recall* detached local commits by referencing or applying them +via commit-id. Although, do not expect to see really old commits in reflog, because +Git regularly [cleans the commits which are *unreachable* by branches or tags][git-autoclean-ref]. + +To view repository history and to track older commits you can use below command + +```shell +$ git reflog show + +# Example output: +b673187 HEAD@{4}: merge 6e43d5987921bde189640cc1e37661f7f75c9c0b: Merge made by the 'recursive' strategy. +eb37e74 HEAD@{5}: rebase -i (finish): returning to refs/heads/master +eb37e74 HEAD@{6}: rebase -i (pick): Commit C +97436c6 HEAD@{7}: rebase -i (start): checkout 97436c6eec6396c63856c19b6a96372705b08b1b +... +88f1867 HEAD@{12}: commit: Commit D +97436c6 HEAD@{13}: checkout: moving from 97436c6eec6396c63856c19b6a96372705b08b1b to test +97436c6 HEAD@{14}: checkout: moving from master to 97436c6 +05cc326 HEAD@{15}: commit: Commit C +6e43d59 HEAD@{16}: commit: Commit B +``` + +Output of command shows repository history. In first column there is commit-id, +in following column, number next to `HEAD` indicates how many commits ago something +was made, after that indicator of action that was made (commit, rebase, merge, ...) +and then on end description of that action. + + +## Undo remote changes without changing history + +This topic is roughly same as modifying committed local changes without modifying +history. **It should be the preferred way of undoing changes on any remote repository +or public branch.** Keep in mind that branching is the best solution when you want +to retain the history of faulty development, yet start anew from certain point. Branching +enables you to include the existing changes in new development (by merging) and +it also provides a clear timeline and development structure. + +![Use revert to keep branch flowing](img/revert.png) + +If you want to revert changes introduced in certain `commit-id` you can simply +revert that `commit-id` (swap additions and deletions) in newly created commit. +You can do this with + +``` +git revert commit-id +``` + +or creating a new branch + +``` +git checkout commit-id +git checkout -b new-path-of-feature +``` + + +## Undo remote changes with modifying history + +This is useful when you want to *hide* certain things - like secret keys, +passwords, SSH keys, etc. It is and should not be used to hide mistakes, as +it will make it harder to debug in case there are some other bugs. The main +reason for this is that you loose the real development progress. **Also keep in +mind that, even with modified history, commits are just detached and can still be +accessed through commit-id** - at least until all repositories perform +the cleanup of detached commits (happens automatically). + +![Modifying history causes problems on remote branch](img/rebase_reset.png) + + +### Where modifying history is generally acceptable + +Modified history breaks the development chain of other developers, as changed +history does not have matching commits'ids. For that reason it should not +be used on any public branch or on branch that *might* be used by other +developers. When contributing to big open source repositories (e.g. [GitLab CE][gitlab-ce]), +it is acceptable to *squash* commits into a single one, to present +a nicer history of your contribution. +Keep in mind that this also removes the comments attached to certain commits +in merge requests, so if you need to retain traceability in GitLab, then +modifying history is not acceptable. +A feature-branch of a merge request is a public branch and might be used by +other developers, but project process and rules might allow or require +you to use `git rebase` (command that changes history) to reduce number of +displayed commits on target branch after reviews are done (for example +GitLab). There is a `git merge --squash` command which does exactly that +(squashes commits on feature-branch to a single commit on target branch +at merge). + +>**Note:** +Never modify the commit history of `master` or shared branch + + +### How modifying history is done + +After you know what you want to modify (how far in history or how which range of +old commits), use `git rebase -i commit-id`. This command will then display all the commits from +current version to chosen commit-id and allow modification, squashing, deletion +of that commits. + +```shell +$ git rebase -i commit1-id..commit3-id +pick +pick +pick + +# Rebase commit1-id..commit3-id onto (3 command(s)) +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# d, drop = remove commit +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +# Note that empty commits are commented out +``` + +>**Note:** +It is important to notice that comment from the output clearly states that, if +you decide to abort, then do not just close your editor (as that will in-fact +modify history), but remove all uncommented lines and save. + +That is one of the reasons why `git rebase` should be used carefully on +shared and remote branches. But don't worry, there will be nothing broken until +you push back to the remote repository (so you can freely explore the +different outcomes locally). + +```shell +# Modify history from commit-id to HEAD (current commit) +git rebase -i commit-id +``` + + +### Deleting sensitive information from commits + +Git also enables you to delete sensitive information from your past commits and +it does modify history in the progress. That is why we have included it in this +section and not as a standalone topic. To do so, you should run the +`git filter-branch`, which enables you to rewrite history with +[certain filters][git-filters-manual]. +This command uses rebase to modify history and if you want to remove certain +file from history altogether use: + +``` +git filter-branch --tree-filter 'rm filename' HEAD +``` + +Since `git filter-branch` command might be slow on big repositories, there are +tools that can use some of Git specifics to enable faster execution of common +tasks (which is exactly what removing sensitive information file is about). +An alternative is [BFG Repo-cleaner][bfg-repo-cleaner]. Keep in mind that these +tools are faster because they do not provide a same fully feature set as `git filter-branch` +does, but focus on specific usecases. + + +## Conclusion + +There are various options of undoing your work with any version control system, but +because of de-centralized nature of Git, these options are multiplied (or limited) +depending on the stage of your process. Git also enables rewriting history, but that +should be avoided as it might cause problems when multiple developers are +contributing to the same codebase. + + + + +[bfg-repo-cleaner]: https://rtyley.github.io/bfg-repo-cleaner/ +[git-autoclean-ref]: https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery +[git-basics]: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository +[git-debug]: https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git +[git-distributed]: https://git-scm.com/about/distributed +[git-filters-manual]: https://git-scm.com/docs/git-filter-branch#_options +[git-official]: https://git-scm.com/ +[gitlab-ce]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria +[gitlab-flow]: https://about.gitlab.com/2014/09/29/gitlab-flow/ +[gitlab-git-tips-n-tricks]: https://about.gitlab.com/2016/12/08/git-tips-and-tricks/ + -- cgit v1.2.1 From f0da0f3a05d3eb379b41c17d36a598718e47cc74 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Fri, 11 Aug 2017 17:05:09 -0300 Subject: general review - minor copyedit - remove duplicate lines - highlight all code blocks - correct puntuaction --- .../numerous_undo_possibilities_in_git/index.md | 128 +++++++++------------ 1 file changed, 57 insertions(+), 71 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/numerous_undo_possibilities_in_git/index.md b/doc/articles/numerous_undo_possibilities_in_git/index.md index 612e2b88190..9f1239b8f88 100644 --- a/doc/articles/numerous_undo_possibilities_in_git/index.md +++ b/doc/articles/numerous_undo_possibilities_in_git/index.md @@ -1,25 +1,24 @@ # Numerous undo possibilities in Git -> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || +> **Article [Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Crt Mori](https://gitlab.com/Letme) || -> **Publication date:** 2017/08/04 +> **Publication date:** 2017/08/17 ## Introduction -In this tutorial, we will show you different ways of undoing in Git, for which +In this tutorial, we will show you different ways of undoing your work in Git, for which we will assume you have a basic working knowledge of. Check GitLab's [Git documentation](../../topics/git/index.md#git-documentation) for reference. Also, we will only provide some general info of the commands, which is enough -to get you started for the easy cases/examples, but you will have to read the -command manual for anything more advanced. +to get you started for the easy cases/examples, but for anything more advanced please refer to the [Git book](https://git-scm.com/book/en/v2). We will explain a few different techniques to undo your changes based on the stage of the change in your current development. Also, keep in mind that [nothing in Git is really deleted.][git-autoclean-ref] This means that until Git automatically cleans detached commits (which cannot be accessed by branch or tag) it will be possible to view them with `git reflog` command -and access them with direct commit-id. You can read more about [redo in below section](#redoing-the-undo). +and access them with direct commit-id. Read more about _[redoing the undo](#redoing-the-undo)_ on the section below. This guide is organized depending on the [stage of development][git-basics] where you want to undo your changes from and if they were shared with other developers @@ -78,7 +77,7 @@ proposes a solution to discard changes to certain file. Suppose you edited a file to change the content using your favorite editor: -``` +```shell vim ``` @@ -101,19 +100,19 @@ At this point there are 3 options to undo the local changes you have: - Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes) - ``` + ```shell git stash ``` - Discarding local changes (permanently) to a file - ``` + ```shell git checkout -- ``` - Discard all local changes to all files permanently - ``` + ```shell git reset --hard ``` @@ -124,7 +123,6 @@ This command resets the changes to all files, but it also saves them in case you would like to apply them at some later time. You can read more about it in [section below](#quickly-save-local-changes). - ### Quickly save local changes You are working on a feature when a boss drops by with an urgent task. Since your @@ -144,7 +142,6 @@ additional options like: - `git stash pop`, which redoes previously stashed changes and removes them from stashed list - `git stash apply`, which redoes previously stashed changes, but keeps them on stashed list - ### Staged local changes (before you commit) Let's say you have added some files to staging, but you want to remove them from the @@ -176,29 +173,28 @@ Now you have 4 options to undo your changes: - Unstage the file to current commit (HEAD) - ``` + ```shell git reset HEAD ``` - Unstage everything - retain changes - ``` + ```shell git reset ``` - Discard all local changes, but save them for [later](#quickly-save-local-changes) - ``` + ```shell git stash ``` - Discard everything permanently - ``` + ```shell git reset --hard ``` - ## Committed local changes Once you commit, your changes are recorded by the version control system. @@ -207,7 +203,6 @@ still not public (or shared with other developers). At this point, undoing things is a lot easier, we have quite some workaround options. Once you push your code, you'll have less options to troubleshoot your work. - ### Without modifying history Through the development process some of the previously committed changes do not @@ -223,7 +218,7 @@ and `B` is the commit you want to undo. There are many different ways to identif `B` as bad, one of them is to pass a range to `git bisect` command. The provided range includes last known good commit (we assume `A`) and first known bad commit (where bug was detected - we will assume `E`). -``` +```shell git bisect A..E ``` @@ -232,23 +227,23 @@ through simple bisection process. You can read more about it [in official Git To In our example we will end up with commit `B`, that introduced bug/error. We have 4 options on how to remove it (or part of it) from our repository. - - Undo (swap additions and deletions) changes introduced by commit `B`. +- Undo (swap additions and deletions) changes introduced by commit `B`. - ``` - git revert commit-B-id - ``` + ```shell + git revert commit-B-id + ``` - - Undo changes on a single file or directory from commit `B`, but retain them in the staged state +- Undo changes on a single file or directory from commit `B`, but retain them in the staged state - ``` - git checkout commit-B-id - ``` + ```shell + git checkout commit-B-id + ``` - - Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state +- Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state - ``` - git reset commit-B-id - ``` + ```shell + git reset commit-B-id + ``` - There is one command we also must not forget: **creating a new branch** from the point where changes are not applicable or where the development has hit a @@ -264,13 +259,12 @@ In our example we will end up with commit `B`, that introduced bug/error. We hav ![Create a new branch to avoid clashing](img/branching.png) - ``` - git checkout commit-B-id - git checkout -b new-path-of-feature - # Create - git commit -a - ``` - + ```shell + git checkout commit-B-id + git checkout -b new-path-of-feature + # Create + git commit -a + ``` ### With history modification @@ -288,34 +282,34 @@ provides interactive mode (`-i` flag) which enables you to: Let us check few examples. Again there are commits `A-B-C-D` where you want to delete commit `B`. - - Rebase the range from current commit D to A +- Rebase the range from current commit D to A: - ``` - git rebase -i A - ``` + ```shell + git rebase -i A + ``` - - Command opens your favorite editor where you write `drop` in front of commit - `B`, but you leave default `pick` with all other commits. Save and exit the - editor to perform a rebase. Remember: if you want to cancel delete whole - file content before saving and exiting the editor +- Command opens your favorite editor where you write `drop` in front of commit + `B`, but you leave default `pick` with all other commits. Save and exit the + editor to perform a rebase. Remember: if you want to cancel delete whole + file content before saving and exiting the editor In case you want to modify something introduced in commit `B`. - - Rebase the range from current commit D to A +- Rebase the range from current commit D to A: - ``` - git rebase -i A - ``` + ```shell + git rebase -i A + ``` - - Command opens your favorite text editor where you write `edit` in front of commit - `B`, but leave default `pick` with all other commits. Save and exit the editor to - perform a rebase +- Command opens your favorite text editor where you write `edit` in front of commit + `B`, but leave default `pick` with all other commits. Save and exit the editor to + perform a rebase - - Now do your edits and commit changes +- Now do your edits and commit changes: - ``` - git commit -a - ``` + ```shell + git commit -a + ``` You can find some more examples in [below section where we explain how to modify history](#how-modifying-history-is-done) @@ -329,7 +323,7 @@ enables you to *recall* detached local commits by referencing or applying them via commit-id. Although, do not expect to see really old commits in reflog, because Git regularly [cleans the commits which are *unreachable* by branches or tags][git-autoclean-ref]. -To view repository history and to track older commits you can use below command +To view repository history and to track older commits you can use below command: ```shell $ git reflog show @@ -352,7 +346,6 @@ in following column, number next to `HEAD` indicates how many commits ago someth was made, after that indicator of action that was made (commit, rebase, merge, ...) and then on end description of that action. - ## Undo remote changes without changing history This topic is roughly same as modifying committed local changes without modifying @@ -365,21 +358,20 @@ it also provides a clear timeline and development structure. ![Use revert to keep branch flowing](img/revert.png) If you want to revert changes introduced in certain `commit-id` you can simply -revert that `commit-id` (swap additions and deletions) in newly created commit. +revert that `commit-id` (swap additions and deletions) in newly created commit: You can do this with -``` +```shell git revert commit-id ``` -or creating a new branch +or creating a new branch: -``` +```shell git checkout commit-id git checkout -b new-path-of-feature ``` - ## Undo remote changes with modifying history This is useful when you want to *hide* certain things - like secret keys, @@ -392,7 +384,6 @@ the cleanup of detached commits (happens automatically). ![Modifying history causes problems on remote branch](img/rebase_reset.png) - ### Where modifying history is generally acceptable Modified history breaks the development chain of other developers, as changed @@ -415,7 +406,6 @@ at merge). >**Note:** Never modify the commit history of `master` or shared branch - ### How modifying history is done After you know what you want to modify (how far in history or how which range of @@ -464,7 +454,6 @@ different outcomes locally). git rebase -i commit-id ``` - ### Deleting sensitive information from commits Git also enables you to delete sensitive information from your past commits and @@ -475,7 +464,7 @@ section and not as a standalone topic. To do so, you should run the This command uses rebase to modify history and if you want to remove certain file from history altogether use: -``` +```shell git filter-branch --tree-filter 'rm filename' HEAD ``` @@ -486,7 +475,6 @@ An alternative is [BFG Repo-cleaner][bfg-repo-cleaner]. Keep in mind that these tools are faster because they do not provide a same fully feature set as `git filter-branch` does, but focus on specific usecases. - ## Conclusion There are various options of undoing your work with any version control system, but @@ -495,7 +483,6 @@ depending on the stage of your process. Git also enables rewriting history, but should be avoided as it might cause problems when multiple developers are contributing to the same codebase. - [bfg-repo-cleaner]: https://rtyley.github.io/bfg-repo-cleaner/ @@ -508,4 +495,3 @@ contributing to the same codebase. [gitlab-ce]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria [gitlab-flow]: https://about.gitlab.com/2014/09/29/gitlab-flow/ [gitlab-git-tips-n-tricks]: https://about.gitlab.com/2016/12/08/git-tips-and-tricks/ - -- cgit v1.2.1 From 4231d1de0d9d177edd12b4e0bce138653d5fd200 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Fri, 11 Aug 2017 17:05:17 -0300 Subject: indexes article --- doc/articles/index.md | 1 + 1 file changed, 1 insertion(+) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 558c624fe39..ce022e855fe 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -44,6 +44,7 @@ Learn how to use [Git with GitLab](../topics/git/index.md): | Article title | Category | Publishing date | | :------------ | :------: | --------------: | +| [Numerous _undo_ possibilities in Git](numerous_undo_possibilities_in_git/index.md) | Tutorial | 2017/08/17 | | [Why Git is Worth the Learning Curve](https://about.gitlab.com/2017/05/17/learning-curve-is-the-biggest-challenge-developers-face-with-git/) | Concepts | 2017/05/17 | | [How to install Git](how_to_install_git/index.md) | Tutorial | 2017/05/15 | | [Getting Started with Git LFS](https://about.gitlab.com/2017/01/30/getting-started-with-git-lfs-tutorial/) | Tutorial | 2017/01/30 | -- cgit v1.2.1 From 28d74d593cbee4b84ed843ab1a2293582284c2ac Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Fri, 11 Aug 2017 17:17:49 -0300 Subject: indexes new article + adjust date formats - index new article - adequate date format according to https://gitlab.com/gitlab-com/www-gitlab-com/commit/3021368c90cec5ec8c63 b93d15a15c47c8b7a917 --- doc/articles/index.md | 106 +++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index ce022e855fe..940e97ca35f 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -17,8 +17,8 @@ Explore GitLab's supported [authentications methods](../topics/authentication/in | Article title | Category | Publishing date | | :------------ | :------: | --------------: | | **LDAP** | -| [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md)| Admin guide | 2017/05/03 | -| [How to configure LDAP with GitLab EE](https://docs.gitlab.com/ee/articles/how_to_configure_ldap_gitlab_ee/) | Admin guide | 2017/05/03 | +| [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md)| Admin guide | 2017-05-03 | +| [How to configure LDAP with GitLab EE](https://docs.gitlab.com/ee/articles/how_to_configure_ldap_gitlab_ee/) | Admin guide | 2017-05-03 | ## Build, test, and deploy with GitLab CI/CD @@ -26,17 +26,17 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017/07/13 | -| [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017/07/11 | -| [Continuous Integration: From Jenkins to GitLab Using Docker](https://about.gitlab.com/2017/07/27/docker-my-precious/) | Concepts | 2017/07/27 | -| [Continuous Delivery of a Spring Boot application with GitLab CI and Kubernetes](https://about.gitlab.com/2016/12/14/continuous-delivery-of-a-spring-boot-application-with-gitlab-ci-and-kubernetes/) | Tutorial | 2016/12/14 | -| [Setting up GitLab CI for Android projects](https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/) | Tutorial | 2016/11/30 | -| [Automated Debian Package Build with GitLab CI](https://about.gitlab.com/2016/10/12/automated-debian-package-build-with-gitlab-ci/) | Tutorial | 2016/10/12 | -| [Building an Elixir Release into a Docker image using GitLab CI](https://about.gitlab.com/2016/08/11/building-an-elixir-release-into-docker-image-using-gitlab-ci-part-1/) | Tutorial | 2016/08/11 | -| [Continuous Delivery with GitLab and Convox](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/) | Technical overview | 2016/06/09 | -| [GitLab Container Registry](https://about.gitlab.com/2016/05/23/gitlab-container-registry/) | Technical overview | 2016/05/23 | -| [How to use GitLab CI and MacStadium to build your macOS or iOS projects](https://about.gitlab.com/2017/05/15/how-to-use-macstadium-and-gitlab-ci-to-build-your-macos-or-ios-projects/) | Technical overview | 2017/05/15 | -| [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/) | Tutorial | 2016/03/10 | +| [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | +| [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | +| [Continuous Integration: From Jenkins to GitLab Using Docker](https://about.gitlab.com/2017/07/27/docker-my-precious/) | Concepts | 2017-07-27 | +| [Continuous Delivery of a Spring Boot application with GitLab CI and Kubernetes](https://about.gitlab.com/2016/12/14/continuous-delivery-of-a-spring-boot-application-with-gitlab-ci-and-kubernetes/) | Tutorial | 2016-12-14 | +| [Setting up GitLab CI for Android projects](https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/) | Tutorial | 2016-11-30 | +| [Automated Debian Package Build with GitLab CI](https://about.gitlab.com/2016/10/12/automated-debian-package-build-with-gitlab-ci/) | Tutorial | 2016-10-12 | +| [Building an Elixir Release into a Docker image using GitLab CI](https://about.gitlab.com/2016/08/11/building-an-elixir-release-into-docker-image-using-gitlab-ci-part-1/) | Tutorial | 2016-08-11 | +| [Continuous Delivery with GitLab and Convox](https://about.gitlab.com/2016/06/09/continuous-delivery-with-gitlab-and-convox/) | Technical overview | 2016-06-09 | +| [GitLab Container Registry](https://about.gitlab.com/2016/05/23/gitlab-container-registry/) | Technical overview | 2016-05-23 | +| [How to use GitLab CI and MacStadium to build your macOS or iOS projects](https://about.gitlab.com/2017/05/15/how-to-use-macstadium-and-gitlab-ci-to-build-your-macos-or-ios-projects/) | Technical overview | 2017-05-15 | +| [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/) | Tutorial | 2016-03-10 | ## Git @@ -44,11 +44,11 @@ Learn how to use [Git with GitLab](../topics/git/index.md): | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [Numerous _undo_ possibilities in Git](numerous_undo_possibilities_in_git/index.md) | Tutorial | 2017/08/17 | -| [Why Git is Worth the Learning Curve](https://about.gitlab.com/2017/05/17/learning-curve-is-the-biggest-challenge-developers-face-with-git/) | Concepts | 2017/05/17 | -| [How to install Git](how_to_install_git/index.md) | Tutorial | 2017/05/15 | -| [Getting Started with Git LFS](https://about.gitlab.com/2017/01/30/getting-started-with-git-lfs-tutorial/) | Tutorial | 2017/01/30 | -| [Git Tips & Tricks](https://about.gitlab.com/2016/12/08/git-tips-and-tricks/) | Technical overview | 2016/12/08 | +| [Numerous _undo_ possibilities in Git](numerous_undo_possibilities_in_git/index.md) | Tutorial | 2017-08-17 | +| [Why Git is Worth the Learning Curve](https://about.gitlab.com/2017/05/17/learning-curve-is-the-biggest-challenge-developers-face-with-git/) | Concepts | 2017-05-17 | +| [How to install Git](how_to_install_git/index.md) | Tutorial | 2017-05-15 | +| [Getting Started with Git LFS](https://about.gitlab.com/2017/01/30/getting-started-with-git-lfs-tutorial/) | Tutorial | 2017-01-30 | +| [Git Tips & Tricks](https://about.gitlab.com/2016/12/08/git-tips-and-tricks/) | Technical overview | 2016-12-08 | ## GitLab Pages @@ -57,21 +57,21 @@ Learn how to deploy a static website with [GitLab Pages](../user/project/pages/i | Article title | Category | Publishing date | | :------------ | :------: | --------------: | | **Series: GitLab Pages from A to Z:** | -| [- Part 1: Static sites and GitLab Pages domains](../user/project/pages/getting_started_part_one.md)| User guide | 2017/02/22 | -| [- Part 2: Quick start guide - Setting up GitLab Pages](../user/project/pages/getting_started_part_two.md)| User guide | 2017/02/22 | -| [- Part 3: Setting Up Custom Domains - DNS Records and SSL/TLS Certificates](../user/project/pages/getting_started_part_three.md)| User guide | 2017/02/22 | -| [- Part 4: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](../user/project/pages/getting_started_part_four.md)| User guide | 2017/02/22 | -| [Setting up GitLab Pages with CloudFlare Certificates](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Tutorial | 2017/02/07 | -| [Building a new GitLab Docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) | Tutorial | 2016/12/07 | -| [Publish Code Coverage Report with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) | Tutorial | 2016/11/03 | -| [GitLab CI: Deployment & Environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) | Tutorial | 2016/08/26 | -| [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/) | Tutorial | 2016/08/19 | +| [- Part 1: Static sites and GitLab Pages domains](../user/project/pages/getting_started_part_one.md)| User guide | 2017-02-22 | +| [- Part 2: Quick start guide - Setting up GitLab Pages](../user/project/pages/getting_started_part_two.md)| User guide | 2017-02-22 | +| [- Part 3: Setting Up Custom Domains - DNS Records and SSL/TLS Certificates](../user/project/pages/getting_started_part_three.md)| User guide | 2017-02-22 | +| [- Part 4: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](../user/project/pages/getting_started_part_four.md)| User guide | 2017-02-22 | +| [Setting up GitLab Pages with CloudFlare Certificates](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Tutorial | 2017-02-07 | +| [Building a new GitLab Docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) | Tutorial | 2016-12-07 | +| [Publish Code Coverage Report with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) | Tutorial | 2016-11-03 | +| [GitLab CI: Deployment & Environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) | Tutorial | 2016-08-26 | +| [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/) | Tutorial | 2016-08-19 | | **Series: Static Site Generator:** | -| [- Part 1: Dynamic vs Static Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | Tutorial | 2016/06/03 | -| [- Part 2: Modern Static Site Generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) | Tutorial | 2016/06/10 | -| [- Part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | Tutorial | 2016/06/17 | -| [Securing your GitLab Pages with TLS and Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) | Tutorial | 2016/04/11 | -| [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) | Tutorial | 2016/04/07 | +| [- Part 1: Dynamic vs Static Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | Tutorial | 2016-06-03 | +| [- Part 2: Modern Static Site Generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) | Tutorial | 2016-06-10 | +| [- Part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | Tutorial | 2016-06-17 | +| [Securing your GitLab Pages with TLS and Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) | Tutorial | 2016-04-11 | +| [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) | Tutorial | 2016-04-07 | ## Install and maintain GitLab @@ -79,10 +79,10 @@ Install, upgrade, integrate, migrate to GitLab: | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [Video Tutorial: Idea to Production on Google Container Engine (GKE)](https://about.gitlab.com/2017/01/23/video-tutorial-idea-to-production-on-google-container-engine-gke/) | Tutorial | 2017/01/23 | -| [How to Setup a GitLab Instance on Microsoft Azure](https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/) | Tutorial | 2016/07/13 | -| [Get started with OpenShift Origin 3 and GitLab](openshift_and_gitlab/index.md) | Tutorial | 2016/06/28 | -| [Getting started with GitLab and DigitalOcean](https://about.gitlab.com/2016/04/27/getting-started-with-gitlab-and-digitalocean/) | Tutorial | 2016/04/27 | +| [Video Tutorial: Idea to Production on Google Container Engine (GKE)](https://about.gitlab.com/2017/01/23/video-tutorial-idea-to-production-on-google-container-engine-gke/) | Tutorial | 2017-01-23 | +| [How to Setup a GitLab Instance on Microsoft Azure](https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/) | Tutorial | 2016-07-13 | +| [Get started with OpenShift Origin 3 and GitLab](openshift_and_gitlab/index.md) | Tutorial | 2016-06-28 | +| [Getting started with GitLab and DigitalOcean](https://about.gitlab.com/2016/04/27/getting-started-with-gitlab-and-digitalocean/) | Tutorial | 2016-04-27 | ## Software development @@ -90,25 +90,25 @@ Explore the best of GitLab's software development's capabilities: | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017/07/13 | -| [From 2/3 of the Self-Hosted Git Market, to the Next-Generation CI System, to Auto DevOps](https://about.gitlab.com/2017/06/29/whats-next-for-gitlab-ci/)| Concepts | 2017/06/29 | -| [Fast and Natural Continuous Integration with GitLab CI](https://about.gitlab.com/2017/05/22/fast-and-natural-continuous-integration-with-gitlab-ci/) | Concepts | 2017/05/22 | -| [Demo: Auto-Deploy from GitLab to an OpenShift Container Cluster](https://about.gitlab.com/2017/05/16/devops-containers-gitlab-openshift/) | Technical overview | 2017/05/16 | -| [Demo: GitLab Service Desk](https://about.gitlab.com/2017/05/09/demo-service-desk/) | Feature highlight | 2017/05/09 | -| [Demo: Mapping Work Versus Time, With Burndown Charts](https://about.gitlab.com/2017/04/25/mapping-work-to-do-versus-time-with-burndown-charts/) | Feature highlight | 2017/04/25 | -| [Demo: Cloud Native Development with GitLab](https://about.gitlab.com/2017/04/18/cloud-native-demo/) | Feature highlight | 2017/04/18 | -| [Demo: Mastering Code Review With GitLab](https://about.gitlab.com/2017/03/17/demo-mastering-code-review-with-gitlab/) | Feature highlight | 2017/03/17 | -| [In 13 minutes from Kubernetes to a complete application development tool](https://about.gitlab.com/2016/11/14/idea-to-production/) | Technical overview | 2016/11/14 | -| [GitLab Workflow, an Overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/) | Technical overview | 2016/10/25 | -| [Trends in Version Control Land: Microservices](https://about.gitlab.com/2016/08/16/trends-in-version-control-land-microservices/) | Concepts | 2016/08/16 | -| [Continuous Integration, Delivery, and Deployment with GitLab](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) | Concepts | 2016/08/05 | -| [Trends in Version Control Land: Innersourcing](https://about.gitlab.com/2016/07/07/trends-version-control-innersourcing/) | Concepts | 2016/07/07 | -| [Tutorial: It's all connected in GitLab](https://about.gitlab.com/2016/03/08/gitlab-tutorial-its-all-connected/) | Technical overview | 2016/03/08 | +| [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | +| [From 2/3 of the Self-Hosted Git Market, to the Next-Generation CI System, to Auto DevOps](https://about.gitlab.com/2017/06/29/whats-next-for-gitlab-ci/)| Concepts | 2017-06-29 | +| [Fast and Natural Continuous Integration with GitLab CI](https://about.gitlab.com/2017/05/22/fast-and-natural-continuous-integration-with-gitlab-ci/) | Concepts | 2017-05-22 | +| [Demo: Auto-Deploy from GitLab to an OpenShift Container Cluster](https://about.gitlab.com/2017/05/16/devops-containers-gitlab-openshift/) | Technical overview | 2017-05-16 | +| [Demo: GitLab Service Desk](https://about.gitlab.com/2017/05/09/demo-service-desk/) | Feature highlight | 2017-05-09 | +| [Demo: Mapping Work Versus Time, With Burndown Charts](https://about.gitlab.com/2017/04/25/mapping-work-to-do-versus-time-with-burndown-charts/) | Feature highlight | 2017-04-25 | +| [Demo: Cloud Native Development with GitLab](https://about.gitlab.com/2017/04/18/cloud-native-demo/) | Feature highlight | 2017-04-18 | +| [Demo: Mastering Code Review With GitLab](https://about.gitlab.com/2017/03/17/demo-mastering-code-review-with-gitlab/) | Feature highlight | 2017-03-17 | +| [In 13 minutes from Kubernetes to a complete application development tool](https://about.gitlab.com/2016/11/14/idea-to-production/) | Technical overview | 2016-11-14 | +| [GitLab Workflow, an Overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/) | Technical overview | 2016-10-25 | +| [Trends in Version Control Land: Microservices](https://about.gitlab.com/2016/08/16/trends-in-version-control-land-microservices/) | Concepts | 2016-08-16 | +| [Continuous Integration, Delivery, and Deployment with GitLab](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) | Concepts | 2016-08-05 | +| [Trends in Version Control Land: Innersourcing](https://about.gitlab.com/2016/07/07/trends-version-control-innersourcing/) | Concepts | 2016-07-07 | +| [Tutorial: It's all connected in GitLab](https://about.gitlab.com/2016/03/08/gitlab-tutorial-its-all-connected/) | Technical overview | 2016-03-08 | ## Technologies | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [Why we are not leaving the cloud](https://about.gitlab.com/2017/03/02/why-we-are-not-leaving-the-cloud/) | Concepts | 2017/03/02 | -| [Why We Chose Vue.js](https://about.gitlab.com/2016/10/20/why-we-chose-vue/) | Concepts | 2016/10/20 | -| [Markdown Kramdown Tips & Tricks](https://about.gitlab.com/2016/07/19/markdown-kramdown-tips-and-tricks/) | Technical overview | 2016/07/19 | +| [Why we are not leaving the cloud](https://about.gitlab.com/2017/03/02/why-we-are-not-leaving-the-cloud/) | Concepts | 2017-03-02 | +| [Why We Chose Vue.js](https://about.gitlab.com/2016/10/20/why-we-chose-vue/) | Concepts | 2016-10-20 | +| [Markdown Kramdown Tips & Tricks](https://about.gitlab.com/2016/07/19/markdown-kramdown-tips-and-tricks/) | Technical overview | 2016-07-19 | -- cgit v1.2.1 From aeb9d418b8bd8f3c6e00d01853122a9c06791dc0 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 15 Aug 2017 11:55:04 +0300 Subject: Rename Artifactory and GitLab article file --- doc/articles/artifactory_and_gitlab/index.md | 247 +++++++++++++++++++++ .../.gitkeep | 0 .../index.md | 247 --------------------- 3 files changed, 247 insertions(+), 247 deletions(-) create mode 100644 doc/articles/artifactory_and_gitlab/index.md delete mode 100644 doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep delete mode 100644 doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md (limited to 'doc/articles') diff --git a/doc/articles/artifactory_and_gitlab/index.md b/doc/articles/artifactory_and_gitlab/index.md new file mode 100644 index 00000000000..5d9c8b17053 --- /dev/null +++ b/doc/articles/artifactory_and_gitlab/index.md @@ -0,0 +1,247 @@ +# How to deploy Maven projects to Artifactory with GitLab CI/CD + +> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || +> **Level:** intermediary || +> **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || +> **Publication date:** 2017/08/03 + +## Introduction + +In this article, we will show how you can leverage the power of [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) +to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/), and then use it from another Maven application as a dependency. + +You'll create two different projects: +- `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) +- `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) + +We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/). +We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it. + +## Create the simple Maven dependency + +### Get the sources + +First of all, you need an application to work with: in this specific it is a simple one, but it could be any Maven application. +This will be the dependency you want to package and deploy to Artifactory, in order to be available to other projects. + +For this article you'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, +so log in to your GitLab account and create a new project with **Import project from ➔ Repo by URL**. + +This application is nothing more than a basic class with a stub for a JUnit based test suite. +It exposes a method called `hello` that accepts a string as input, and prints a hello message on the screen. + +The project structure is really simple, and you should consider these two resources: +- `pom.xml`: project object model (POM) configuration file +- `src/main/java/com/example/dep/Dep.java`: source of our application + +### Configure Artifactory deployment + +The application is ready to use, but you need some additional steps to deploy it to Artifactory: +1. log in to Artifactory with your user's credentials +2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel +3. copy to clipboard the configuration snippet under the **Deploy** paragraph +4. change the `url` value in order to have it configurable via secret variables +5. copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section + +The snippet should look like this: + +```xml + + + central + 83d43b5afeb5-releases + ${env.MAVEN_REPO_URL}/libs-release-local + + +``` + +Another step you need to do before you can deploy the dependency to Artifactory is to configure authentication data. +It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. + +Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home +and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one: +1. create a folder called `.m2` in the root of the repo +2. create a file called `settings.xml` in the `.m2` folder +3. copy the following content into `settings.xml` + +```xml + + + + central + ${env.MAVEN_REPO_USER} + ${env.MAVEN_REPO_PASS} + + + +``` + +>**Note**: +`username` and `password` will be replaced by the correct values using secret variables. + +### Configure GitLab CI/CD for `simple-maven-dep` + +Now it's time we set up [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and deploy the dependency! + +[GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs +that will be executed by the configured GitLab Runners. You can read more about this file in the [GitLab Documentation](https://docs.gitlab.com/ee/ci/yaml/). + +First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > Pipelines** page +and add the following secret variables (replace them with your current values, of course): +- **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) +- **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) +- **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password) + +Now it's time to define jobs in `.gitlab-ci.yml` file: once pushed to the repo it will instruct the GitLab Runner with all the needed commands. + +```yaml +image: maven:latest + +variables: + MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" + +cache: + paths: + - .m2/repository/ + - target/ + +build: + stage: build + script: + - mvn $MAVEN_CLI_OPTS compile + +test: + stage: test + script: + - mvn $MAVEN_CLI_OPTS test + +deploy: + stage: deploy + script: + - mvn $MAVEN_CLI_OPTS deploy + only: + - master +``` + +GitLab Runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project, +in order to run the jobs. +Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home when searching for configuration and dependencies. +Caching the `.m2/repository folder` (where all the Maven files are stored), and the `target` folder (where our application will be created), is useful for speeding up the process +by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. +Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the application. + +Deploy to Artifactory is done as defined by the secret variables we have just set up. +The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published. + +Done! Now you have all the changes in the GitLab repo, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening. +If the deployment has been successful, the deploy job log will output: + +``` +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 1.983 s + +``` + +>**Note**: +the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log the first time you run it. + +Yay! You did it! Checking in Artifactory will confirm that you have a new artifact available in the `libs-release-local` repo. + +## Create the main Maven application + +### Prepare the application + +Now that you have the dependency available on Artifactory, you want to use it! + +Create another application by cloning the one you can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. +If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. + +Since Maven doesn't know how to resolve the dependency, you need to modify the configuration: +1. go back to Artifactory +2. browse the `libs-release-local` repository +3. select the `simple-maven-dep-1.0.jar` file +4. find the configuration snippet from the **Dependency Declaration** section of the main panel +5. copy the snippet in the `dependencies` section of the `pom.xml` file + +The snippet should look like this: + +```xml + + com.example.dep + simple-maven-dep + 1.0 + +``` + +### Configure the Artifactory repository location + +At this point you defined the dependency for the application, but you still miss where you can find the required files. +You need to create a `.m2/settings.xml` file as you did for the dependency project, and let Maven know the location using environment variables. + +Here is how you can get the content of the file directly from Artifactory: +1. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel +2. click on **Generate Maven Settings** +3. click on **Generate Settings** +3. copy to clipboard the configuration file +4. save the file as `.m2/settings.xml` in your repo + +Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your application! + +### Configure GitLab CI/CD for `simple-maven-app` + +You need a last step to have everything in place: configure the `.gitlab-ci.yml` file for this project, as you already did for `simple-maven-dep`. + +You want to leverage [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and run your awesome application, +and see if you can get the greeting as expected! + +All you need to do is to add the following `.gitlab-ci.yml` to the repo: + +```yaml +image: maven:latest + +stages: + - build + - test + - run + +variables: + MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" + +cache: + paths: + - .m2/repository/ + - target/ + +build: + stage: build + script: + - mvn $MAVEN_CLI_OPTS compile + +test: + stage: test + script: + - mvn $MAVEN_CLI_OPTS test + +run: + stage: run + script: + - mvn $MAVEN_CLI_OPTS package + - mvn $MAVEN_CLI_OPTS exec:java -Dexec.mainClass="com.example.app.App" +``` + +It is very similar to the configuration used for `simple-maven-dep`, but instead of the `deploy` job there is a `run` job. +Probably something that you don't want to use in real projects, but here it is useful to see the application executed automatically. + +And that's it! In the `run` job output log you will find a friendly hello to GitLab! + +## Conclusion + +In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume artifacts. + +A similar approach could be used to interact with any other Maven compatible Binary Repository Manager. +Obviously, you can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. \ No newline at end of file diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md b/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md deleted file mode 100644 index 5d9c8b17053..00000000000 --- a/doc/articles/how_to_use_gitlab_ci_to_deploy_maven_projects_to_artifactory/index.md +++ /dev/null @@ -1,247 +0,0 @@ -# How to deploy Maven projects to Artifactory with GitLab CI/CD - -> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || -> **Level:** intermediary || -> **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || -> **Publication date:** 2017/08/03 - -## Introduction - -In this article, we will show how you can leverage the power of [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) -to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/), and then use it from another Maven application as a dependency. - -You'll create two different projects: -- `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) -- `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) - -We assume that you already have a GitLab account on [GitLab.com](https://gitlab.com/), and that you know the basic usage of Git and [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/). -We also assume that an Artifactory instance is available and reachable from the internet, and that you have valid credentials to deploy on it. - -## Create the simple Maven dependency - -### Get the sources - -First of all, you need an application to work with: in this specific it is a simple one, but it could be any Maven application. -This will be the dependency you want to package and deploy to Artifactory, in order to be available to other projects. - -For this article you'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, -so log in to your GitLab account and create a new project with **Import project from ➔ Repo by URL**. - -This application is nothing more than a basic class with a stub for a JUnit based test suite. -It exposes a method called `hello` that accepts a string as input, and prints a hello message on the screen. - -The project structure is really simple, and you should consider these two resources: -- `pom.xml`: project object model (POM) configuration file -- `src/main/java/com/example/dep/Dep.java`: source of our application - -### Configure Artifactory deployment - -The application is ready to use, but you need some additional steps to deploy it to Artifactory: -1. log in to Artifactory with your user's credentials -2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel -3. copy to clipboard the configuration snippet under the **Deploy** paragraph -4. change the `url` value in order to have it configurable via secret variables -5. copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section - -The snippet should look like this: - -```xml - - - central - 83d43b5afeb5-releases - ${env.MAVEN_REPO_URL}/libs-release-local - - -``` - -Another step you need to do before you can deploy the dependency to Artifactory is to configure authentication data. -It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. - -Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home -and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one: -1. create a folder called `.m2` in the root of the repo -2. create a file called `settings.xml` in the `.m2` folder -3. copy the following content into `settings.xml` - -```xml - - - - central - ${env.MAVEN_REPO_USER} - ${env.MAVEN_REPO_PASS} - - - -``` - ->**Note**: -`username` and `password` will be replaced by the correct values using secret variables. - -### Configure GitLab CI/CD for `simple-maven-dep` - -Now it's time we set up [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and deploy the dependency! - -[GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs -that will be executed by the configured GitLab Runners. You can read more about this file in the [GitLab Documentation](https://docs.gitlab.com/ee/ci/yaml/). - -First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > Pipelines** page -and add the following secret variables (replace them with your current values, of course): -- **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) -- **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) -- **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password) - -Now it's time to define jobs in `.gitlab-ci.yml` file: once pushed to the repo it will instruct the GitLab Runner with all the needed commands. - -```yaml -image: maven:latest - -variables: - MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" - MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" - -cache: - paths: - - .m2/repository/ - - target/ - -build: - stage: build - script: - - mvn $MAVEN_CLI_OPTS compile - -test: - stage: test - script: - - mvn $MAVEN_CLI_OPTS test - -deploy: - stage: deploy - script: - - mvn $MAVEN_CLI_OPTS deploy - only: - - master -``` - -GitLab Runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project, -in order to run the jobs. -Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home when searching for configuration and dependencies. -Caching the `.m2/repository folder` (where all the Maven files are stored), and the `target` folder (where our application will be created), is useful for speeding up the process -by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. -Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the application. - -Deploy to Artifactory is done as defined by the secret variables we have just set up. -The deployment occurs only if we're pushing or merging to `master` branch, so that the development versions are tested but not published. - -Done! Now you have all the changes in the GitLab repo, and a pipeline has already been started for this commit. In the **Pipelines** tab you can see what's happening. -If the deployment has been successful, the deploy job log will output: - -``` -[INFO] ------------------------------------------------------------------------ -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 1.983 s - -``` - ->**Note**: -the `mvn` command downloads a lot of files from the internet, so you'll see a lot of extra activity in the log the first time you run it. - -Yay! You did it! Checking in Artifactory will confirm that you have a new artifact available in the `libs-release-local` repo. - -## Create the main Maven application - -### Prepare the application - -Now that you have the dependency available on Artifactory, you want to use it! - -Create another application by cloning the one you can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. -If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. - -Since Maven doesn't know how to resolve the dependency, you need to modify the configuration: -1. go back to Artifactory -2. browse the `libs-release-local` repository -3. select the `simple-maven-dep-1.0.jar` file -4. find the configuration snippet from the **Dependency Declaration** section of the main panel -5. copy the snippet in the `dependencies` section of the `pom.xml` file - -The snippet should look like this: - -```xml - - com.example.dep - simple-maven-dep - 1.0 - -``` - -### Configure the Artifactory repository location - -At this point you defined the dependency for the application, but you still miss where you can find the required files. -You need to create a `.m2/settings.xml` file as you did for the dependency project, and let Maven know the location using environment variables. - -Here is how you can get the content of the file directly from Artifactory: -1. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel -2. click on **Generate Maven Settings** -3. click on **Generate Settings** -3. copy to clipboard the configuration file -4. save the file as `.m2/settings.xml` in your repo - -Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your application! - -### Configure GitLab CI/CD for `simple-maven-app` - -You need a last step to have everything in place: configure the `.gitlab-ci.yml` file for this project, as you already did for `simple-maven-dep`. - -You want to leverage [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and run your awesome application, -and see if you can get the greeting as expected! - -All you need to do is to add the following `.gitlab-ci.yml` to the repo: - -```yaml -image: maven:latest - -stages: - - build - - test - - run - -variables: - MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" - MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" - -cache: - paths: - - .m2/repository/ - - target/ - -build: - stage: build - script: - - mvn $MAVEN_CLI_OPTS compile - -test: - stage: test - script: - - mvn $MAVEN_CLI_OPTS test - -run: - stage: run - script: - - mvn $MAVEN_CLI_OPTS package - - mvn $MAVEN_CLI_OPTS exec:java -Dexec.mainClass="com.example.app.App" -``` - -It is very similar to the configuration used for `simple-maven-dep`, but instead of the `deploy` job there is a `run` job. -Probably something that you don't want to use in real projects, but here it is useful to see the application executed automatically. - -And that's it! In the `run` job output log you will find a friendly hello to GitLab! - -## Conclusion - -In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume artifacts. - -A similar approach could be used to interact with any other Maven compatible Binary Repository Manager. -Obviously, you can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. \ No newline at end of file -- cgit v1.2.1 From f285d01600d055407f42283c81acc3354125f2e0 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 15 Aug 2017 12:28:18 +0300 Subject: Copyedit Artifactory and GitLab article --- doc/articles/artifactory_and_gitlab/index.md | 185 ++++++++++++++++----------- doc/articles/index.md | 1 + 2 files changed, 109 insertions(+), 77 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/artifactory_and_gitlab/index.md b/doc/articles/artifactory_and_gitlab/index.md index 5d9c8b17053..7334191551c 100644 --- a/doc/articles/artifactory_and_gitlab/index.md +++ b/doc/articles/artifactory_and_gitlab/index.md @@ -11,6 +11,7 @@ In this article, we will show how you can leverage the power of [GitLab CI/CD](h to build a [Maven](https://maven.apache.org/) project, deploy it to [Artifactory](https://www.jfrog.com/artifactory/), and then use it from another Maven application as a dependency. You'll create two different projects: + - `simple-maven-dep`: the app built and deployed to Artifactory (available at https://gitlab.com/gitlab-examples/maven/simple-maven-dep) - `simple-maven-app`: the app using the previous one as a dependency (available at https://gitlab.com/gitlab-examples/maven/simple-maven-app) @@ -19,81 +20,97 @@ We also assume that an Artifactory instance is available and reachable from the ## Create the simple Maven dependency -### Get the sources +First of all, you need an application to work with: in this specific case we will +use a simple one, but it could be any Maven application. This will be the +dependency you want to package and deploy to Artifactory, in order to be +available to other projects. + +### Prepare the dependency application + +For this article you'll use a Maven app that can be cloned from our example +project: -First of all, you need an application to work with: in this specific it is a simple one, but it could be any Maven application. -This will be the dependency you want to package and deploy to Artifactory, in order to be available to other projects. +1. Log in to your GitLab account +1. Create a new project by selecting **Import project from ➔ Repo by URL** +1. Add the following URL: -For this article you'll use a Maven app that can be cloned from `https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git`, -so log in to your GitLab account and create a new project with **Import project from ➔ Repo by URL**. + ``` + https://gitlab.com/gitlab-examples/maven/simple-maven-dep.git + ``` +1. Click **Create project** This application is nothing more than a basic class with a stub for a JUnit based test suite. It exposes a method called `hello` that accepts a string as input, and prints a hello message on the screen. The project structure is really simple, and you should consider these two resources: + - `pom.xml`: project object model (POM) configuration file - `src/main/java/com/example/dep/Dep.java`: source of our application -### Configure Artifactory deployment +### Configure the Artifactory deployment The application is ready to use, but you need some additional steps to deploy it to Artifactory: -1. log in to Artifactory with your user's credentials -2. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel -3. copy to clipboard the configuration snippet under the **Deploy** paragraph -4. change the `url` value in order to have it configurable via secret variables -5. copy the snippet in the `pom.xml` file for your project, just after the `dependencies` section - -The snippet should look like this: - -```xml - - - central - 83d43b5afeb5-releases - ${env.MAVEN_REPO_URL}/libs-release-local - - -``` -Another step you need to do before you can deploy the dependency to Artifactory is to configure authentication data. -It is a simple task, but Maven requires it to stay in a file called `settings.xml` that has to be in the `.m2` subfolder in the user's homedir. - -Since you want to use GitLab Runner to automatically deploy the application, you should create the file in the project home -and set a command line parameter in `.gitlab-ci.yml` to use the custom location instead of the default one: -1. create a folder called `.m2` in the root of the repo -2. create a file called `settings.xml` in the `.m2` folder -3. copy the following content into `settings.xml` - -```xml - - - - central - ${env.MAVEN_REPO_USER} - ${env.MAVEN_REPO_PASS} - - - -``` - ->**Note**: -`username` and `password` will be replaced by the correct values using secret variables. +1. Log in to Artifactory with your user's credentials. +1. From the main screen, click on the `libs-release-local` item in the **Set Me Up** panel. +1. Copy to clipboard the configuration snippet under the **Deploy** paragraph. +1. Change the `url` value in order to have it configurable via secret variables. +1. Copy the snippet in the `pom.xml` file for your project, just after the + `dependencies` section. The snippet should look like this: + + ```xml + + + central + 83d43b5afeb5-releases + ${env.MAVEN_REPO_URL}/libs-release-local + + + ``` + +Another step you need to do before you can deploy the dependency to Artifactory +is to configure the authentication data. It is a simple task, but Maven requires +it to stay in a file called `settings.xml` that has to be in the `.m2` subdirectory +in the user's homedir. + +Since you want to use GitLab Runner to automatically deploy the application, you +should create the file in the project's home directory and set a command line +parameter in `.gitlab-ci.yml` to use the custom location instead of the default one: + +1. Create a folder called `.m2` in the root of your repository +1. Create a file called `settings.xml` in the `.m2` folder +1. Copy the following content into a `settings.xml` file: + + ```xml + + + + central + ${env.MAVEN_REPO_USER} + ${env.MAVEN_REPO_PASS} + + + + ``` + + Username and password will be replaced by the correct values using secret variables. ### Configure GitLab CI/CD for `simple-maven-dep` Now it's time we set up [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) to automatically build, test and deploy the dependency! -[GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/) uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs +GitLab CI/CD uses a file in the root of the repo, named `.gitlab-ci.yml`, to read the definitions for jobs that will be executed by the configured GitLab Runners. You can read more about this file in the [GitLab Documentation](https://docs.gitlab.com/ee/ci/yaml/). -First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > Pipelines** page +First of all, remember to set up secret variables for your deployment. Navigate to your project's **Settings > CI/CD** page and add the following secret variables (replace them with your current values, of course): + - **MAVEN_REPO_URL**: `http://artifactory.example.com:8081/artifactory` (your Artifactory URL) - **MAVEN_REPO_USER**: `gitlab` (your Artifactory username) - **MAVEN_REPO_PASS**: `AKCp2WXr3G61Xjz1PLmYa3arm3yfBozPxSta4taP3SeNu2HPXYa7FhNYosnndFNNgoEds8BCS` (your Artifactory Encrypted Password) -Now it's time to define jobs in `.gitlab-ci.yml` file: once pushed to the repo it will instruct the GitLab Runner with all the needed commands. +Now it's time to define jobs in `.gitlab-ci.yml` and push it to the repo: ```yaml image: maven:latest @@ -127,9 +144,12 @@ deploy: GitLab Runner will use the latest [Maven Docker image](https://hub.docker.com/_/maven/), which already contains all the tools and the dependencies you need to manage the project, in order to run the jobs. + Environment variables are set to instruct Maven to use the `homedir` of the repo instead of the user's home when searching for configuration and dependencies. + Caching the `.m2/repository folder` (where all the Maven files are stored), and the `target` folder (where our application will be created), is useful for speeding up the process by running all Maven phases in a sequential order, therefore, executing `mvn test` will automatically run `mvn compile` if necessary. + Both `build` and `test` jobs leverage the `mvn` command to compile the application and to test it as defined in the test suite that is part of the application. Deploy to Artifactory is done as defined by the secret variables we have just set up. @@ -143,7 +163,6 @@ If the deployment has been successful, the deploy job log will output: [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.983 s - ``` >**Note**: @@ -153,43 +172,55 @@ Yay! You did it! Checking in Artifactory will confirm that you have a new artifa ## Create the main Maven application -### Prepare the application +Now that you have the dependency available on Artifactory, it's time to use it! +Let's see how we can have it as a dependency to our main application. -Now that you have the dependency available on Artifactory, you want to use it! +### Prepare the main application -Create another application by cloning the one you can find at `https://gitlab.com/gitlab-examples/maven/simple-maven-app.git`. -If you look at the `src/main/java/com/example/app/App.java` file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. +We'll use again a Maven app that can be cloned from our example project: -Since Maven doesn't know how to resolve the dependency, you need to modify the configuration: -1. go back to Artifactory -2. browse the `libs-release-local` repository -3. select the `simple-maven-dep-1.0.jar` file -4. find the configuration snippet from the **Dependency Declaration** section of the main panel -5. copy the snippet in the `dependencies` section of the `pom.xml` file +1. Create a new project by selecting **Import project from ➔ Repo by URL** +1. Add the following URL: -The snippet should look like this: + ``` + https://gitlab.com/gitlab-examples/maven/simple-maven-app.git + ``` +1. Click **Create project** -```xml - - com.example.dep - simple-maven-dep - 1.0 - -``` +This one is a simple app as well. If you look at the `src/main/java/com/example/app/App.java` +file you can see that it imports the `com.example.dep.Dep` class and calls the `hello` method passing `GitLab` as a parameter. + +Since Maven doesn't know how to resolve the dependency, you need to modify the configuration: + +1. Go back to Artifactory +1. Browse the `libs-release-local` repository +1. Select the `simple-maven-dep-1.0.jar` file +1. Find the configuration snippet from the **Dependency Declaration** section of the main panel +1. Copy the snippet in the `dependencies` section of the `pom.xml` file. + The snippet should look like this: + + ```xml + + com.example.dep + simple-maven-dep + 1.0 + + ``` ### Configure the Artifactory repository location -At this point you defined the dependency for the application, but you still miss where you can find the required files. +At this point you defined the dependency for the application, but you still miss where you can find the required files. You need to create a `.m2/settings.xml` file as you did for the dependency project, and let Maven know the location using environment variables. Here is how you can get the content of the file directly from Artifactory: -1. from the main screen, click on the `libs-release-local` item in the **Set Me Up** panel -2. click on **Generate Maven Settings** -3. click on **Generate Settings** -3. copy to clipboard the configuration file -4. save the file as `.m2/settings.xml` in your repo -Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your application! +1. From the main screen, click on the `libs-release-local` item in the **Set Me Up** panel +1. Click on **Generate Maven Settings** +1. Click on **Generate Settings** +1. Copy to clipboard the configuration file +1. Save the file as `.m2/settings.xml` in your repo + +Now you are ready to use the Artifactory repository to resolve dependencies and use `simple-maven-dep` in your main application! ### Configure GitLab CI/CD for `simple-maven-app` @@ -244,4 +275,4 @@ And that's it! In the `run` job output log you will find a friendly hello to Git In this article we covered the basic steps to use an Artifactory Maven repository to automatically publish and consume artifacts. A similar approach could be used to interact with any other Maven compatible Binary Repository Manager. -Obviously, you can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. \ No newline at end of file +Obviously, you can improve these examples, optimizing the `.gitlab-ci.yml` file to better suit your needs, and adapting to your workflow. diff --git a/doc/articles/index.md b/doc/articles/index.md index 558c624fe39..e784b42ba99 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -37,6 +37,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | [GitLab Container Registry](https://about.gitlab.com/2016/05/23/gitlab-container-registry/) | Technical overview | 2016/05/23 | | [How to use GitLab CI and MacStadium to build your macOS or iOS projects](https://about.gitlab.com/2017/05/15/how-to-use-macstadium-and-gitlab-ci-to-build-your-macos-or-ios-projects/) | Technical overview | 2017/05/15 | | [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/) | Tutorial | 2016/03/10 | +| [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017/08/03 | ## Git -- cgit v1.2.1 From 06785f92a13f9f722515cc2363569437c9ccd339 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Tue, 15 Aug 2017 14:40:39 +0000 Subject: Update publication date --- doc/articles/artifactory_and_gitlab/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/artifactory_and_gitlab/index.md b/doc/articles/artifactory_and_gitlab/index.md index 7334191551c..2a9957dc0bd 100644 --- a/doc/articles/artifactory_and_gitlab/index.md +++ b/doc/articles/artifactory_and_gitlab/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || -> **Publication date:** 2017/08/03 +> **Publication date:** 2017-08-15 ## Introduction -- cgit v1.2.1 From a54865f4994d4e01aa4f4d9fe153b0cd815d3e57 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 15 Aug 2017 14:16:35 -0300 Subject: fix date format --- doc/articles/how_to_configure_ldap_gitlab_ce/index.md | 2 +- doc/articles/how_to_install_git/index.md | 2 +- doc/articles/openshift_and_gitlab/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/how_to_configure_ldap_gitlab_ce/index.md b/doc/articles/how_to_configure_ldap_gitlab_ce/index.md index 130e8f542b4..25a24bc1d32 100644 --- a/doc/articles/how_to_configure_ldap_gitlab_ce/index.md +++ b/doc/articles/how_to_configure_ldap_gitlab_ce/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** admin guide || > **Level:** intermediary || > **Author:** [Chris Wilson](https://gitlab.com/MrChrisW) || -> **Publication date:** 2017/05/03 +> **Publication date:** 2017-05-03 ## Introduction diff --git a/doc/articles/how_to_install_git/index.md b/doc/articles/how_to_install_git/index.md index 66d866b2d09..37b60501ce2 100644 --- a/doc/articles/how_to_install_git/index.md +++ b/doc/articles/how_to_install_git/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** user guide || > **Level:** beginner || > **Author:** [Sean Packham](https://gitlab.com/SeanPackham) || -> **Publication date:** 2017/05/15 +> **Publication date:** 2017-05-15 To begin contributing to GitLab projects you will need to install the Git client on your computer. diff --git a/doc/articles/openshift_and_gitlab/index.md b/doc/articles/openshift_and_gitlab/index.md index 7f76e577efa..c0bbcfe2a8a 100644 --- a/doc/articles/openshift_and_gitlab/index.md +++ b/doc/articles/openshift_and_gitlab/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Achilleas Pipinellis](https://gitlab.com/axil) || -> **Publication date:** 2016/06/28 +> **Publication date:** 2016-06-28 ## Introduction -- cgit v1.2.1 From f3f540af82e1ae17828df79c86f1e2ecff707d85 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 15 Aug 2017 14:16:53 -0300 Subject: fix relative link --- doc/articles/artifactory_and_gitlab/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/artifactory_and_gitlab/index.md b/doc/articles/artifactory_and_gitlab/index.md index 2a9957dc0bd..c64851bad2b 100644 --- a/doc/articles/artifactory_and_gitlab/index.md +++ b/doc/articles/artifactory_and_gitlab/index.md @@ -1,6 +1,6 @@ # How to deploy Maven projects to Artifactory with GitLab CI/CD -> **Article [Type](../../development/writing_documentation.html#types-of-technical-articles):** tutorial || +> **Article [Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Fabio Busatto](https://gitlab.com/bikebilly) || > **Publication date:** 2017-08-15 -- cgit v1.2.1 From 7a11a03f2d9e653e362238e6885b49a462de761c Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 15 Aug 2017 14:17:14 -0300 Subject: new articles come first --- doc/articles/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index e784b42ba99..3039faca411 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,6 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | +| [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017/07/13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017/07/11 | | [Continuous Integration: From Jenkins to GitLab Using Docker](https://about.gitlab.com/2017/07/27/docker-my-precious/) | Concepts | 2017/07/27 | @@ -37,7 +38,6 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | [GitLab Container Registry](https://about.gitlab.com/2016/05/23/gitlab-container-registry/) | Technical overview | 2016/05/23 | | [How to use GitLab CI and MacStadium to build your macOS or iOS projects](https://about.gitlab.com/2017/05/15/how-to-use-macstadium-and-gitlab-ci-to-build-your-macos-or-ios-projects/) | Technical overview | 2017/05/15 | | [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/) | Tutorial | 2016/03/10 | -| [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017/08/03 | ## Git -- cgit v1.2.1 From 986b80d0d13f3e95ed02fd721631bebcd94648c1 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 24 Aug 2017 21:31:39 +0000 Subject: New doc: how to install GitLab on Azure --- doc/articles/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 1aa65504852..4b0c85b9272 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -76,7 +76,8 @@ Learn how to deploy a static website with [GitLab Pages](../user/project/pages/i ## Install and maintain GitLab -Install, upgrade, integrate, migrate to GitLab: +[Admin](../README.md#administrator-documentation), [install](../install/README.md), +upgrade, integrate, migrate to GitLab: | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -- cgit v1.2.1 From 9aaf3de01dcfeb311bee2097d5cd7eed218d925e Mon Sep 17 00:00:00 2001 From: Mehran Rasulian Date: Tue, 29 Aug 2017 20:05:00 +0000 Subject: Test and deploy Laravel applications with GitLab CI and Envoy --- .../.gitkeep | 0 .../img/.gitkeep | 0 .../img/container-registry-page-empty-image.png | Bin 0 -> 22449 bytes .../img/container_registry_checkbox.png | Bin 0 -> 4730 bytes .../img/deploy-keys-page.png | Bin 0 -> 54281 bytes .../img/environment_page.png | Bin 0 -> 82411 bytes .../img/environments_page.png | Bin 0 -> 61335 bytes .../img/laravel-welcome-page.png | Bin 0 -> 5785 bytes .../img/pipeline_page.png | Bin 0 -> 75901 bytes .../img/pipelines_page.png | Bin 0 -> 52963 bytes .../img/pipelines_page_deploy_button.png | Bin 0 -> 62798 bytes .../img/production-server-app-directory.png | Bin 0 -> 11082 bytes .../img/production-server-current-directory.png | Bin 0 -> 21993 bytes .../img/secret-variables-page.png | Bin 0 -> 33815 bytes ...ravel_applications_with_gitlab_ci_and_envoy.png | Bin 0 -> 177704 bytes .../index.md | 675 +++++++++++++++++++++ 16 files changed, 675 insertions(+) create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png new file mode 100644 index 00000000000..1f52e1afe83 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png new file mode 100644 index 00000000000..a56c07a0da7 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png new file mode 100644 index 00000000000..d0ce425fbf4 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png new file mode 100644 index 00000000000..1eff36cc859 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png new file mode 100644 index 00000000000..23ce3ee05e7 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png new file mode 100644 index 00000000000..3bb21fd12b4 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png new file mode 100644 index 00000000000..503d22f489d Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png new file mode 100644 index 00000000000..651ea0f00dc Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png new file mode 100644 index 00000000000..35300963de6 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png new file mode 100644 index 00000000000..6dbc29fc25c Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png new file mode 100644 index 00000000000..8a6dcccfa38 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png new file mode 100644 index 00000000000..3249ff9d4e6 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png new file mode 100644 index 00000000000..bc188f83fb1 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md new file mode 100644 index 00000000000..475123a44a0 --- /dev/null +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -0,0 +1,675 @@ +# Test and deploy Laravel applications with GitLab CI and Envoy + +> **Type:** tutorial || +> **Level:** intermediary || +> **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || +> **Publication date:** 2017/06/14 + +## Introduction + +GitLab features our applications with Continuous Integration, and it is possible to deploy the new code changes to the production server whenever we want just by clicking a button! + +In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI](/gitlab-ci/) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). + +We assume you have a basic experience with Laravel, Linux servers, +and you know how to use GitLab. + +Laravel is a high quality web framework written in PHP. +It has a great community with a [fantastic documentation](https://laravel.com/docs). +Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others. + +We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner which is based on PHP. +It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers. +Those tasks can be cloning your project from the repository, installing the Composer dependencies, running [Artisan commands](https://laravel.com/docs/artisan) and more. + +## Initialize our Laravel app on GitLab + +We assume [you have installed a new laravel project](https://laravel.com/docs/installation#installation), so we start with writing a unit test, and initialize the git for the project. + +### Unit Test + +Every new installation of Laravel (currently 5.4) comes with two type of tests 'Feature' and 'Unit' placed in the tests directory. +Here's a unit test from `test/Unit/ExampleTest.php`: + +```php +assertTrue(true); + } +} +``` + +This test is as simple as asserting that the given value is true! + +Laravel uses `PHPUnit` for tests by default. +If we run `vendor/bin/phpunit` we should see green! + +```bash +vendor/bin/phpunit +OK (1 test, 1 assertions) +``` + +This test will be used later for continuously testing our app with GitLab CI. + +### Push to GitLab + +Since we have our app up and running locally, it's time to push the codebase to our remote repository. +Let's create [a new project](https://docs.gitlab.com/ee/gitlab-basics/create-project.html) in GitLab named `laravel-sample`. +After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and do the first commit. + + +```bash +cd laravel-sample +git init +git remote add origin git@gitlab.example.com:/laravel-sample.git +git add . +git commit -m 'Initial Commit' +git push -u origin master +``` + +## Configure the production server + +Before we begin setting up Envoy and GitLab CI, let's quickly make sure the production server is ready for deployment. +We have installed LEMP stack which stands for Linux, Nginx, MySQL and PHP on our Ubuntu 16.04. + +### Create a new user + +Let's now create a new user that will be used to deploy our website and give it +the needed permissions using [Linux ACL](https://serversforhackers.com/video/linux-acls): + +```bash +# Create user deployer +sudo adduser deployer +# Give the read-write-execute permissions to deployer user for directory /var/www +sudo setfacl -R -m u:deployer:rwx /var/www +``` + +If you don't have ACL installed on your Ubuntu server, use this command to install it: + +```bash +sudo apt install acl +``` + +### Add SSH key + +Let's suppose we want to deploy our app to the production server from a private repository on GitLab. First, we need to [generate a new SSH key pair **with no passphrase**](../../ssh/README.md) for the deployer user. + +After that, we need to copy the private key, which will be used to connect to our server as the deployer user with SSH, to be able to automate our deployment process: + +```bash +# As the deployer user on server +# +# Copy the content of public key to authorized_keys +cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys +# Copy the private key text block +cat ~/.ssh/id_rsa +``` + +Now, add it to your GitLab project as a [secret variable](../../ci/variables/README.html#secret-variables). +Secret variables are user-defined variables and are stored out of `.gitlab-ci.yml`, for security purposes. +They can be added per project by navigating to **Project** > **Settings** > **CI/CD Pipelines**. + +![secret variables page](img/secret_variables_page.png) + +To the field **KEY**, add the name `SSH_PRIVATE_KEY`, and to the **VALUE** field, paste the private key you've copied earlier. +We'll use this variable in the `.gitlab-ci.yml` later, to easily connect to our remote server as the deployer user without entering its password. + +We also need to add the public key to **Project** > **Settings** > **Repository** as [Deploy Keys](../../ce/ssh/README.html/#deploy-keys), which gives us the ability to access our repository from the server through [SSH protocol](../../ee/gitlab-basics/command-line-commands.html/#start-working-on-your-project). + + +```bash +# As the deployer user on the server +# +# Copy the public key +cat ~/.ssh/id_rsa.pub +``` + +![deploy keys page](img/deploy_keys_page.png) + +To the field **Title**, add any name you want, and paste the public key into the **Key** field. + +Now, let's clone our repository on the server just to make sure the `deployer` user has access to the repository. + +```bash +# As the deployer user on server +# +git clone git@gitlab.example.com:/laravel-sample.git +``` + +>**Note:** +Answer **yes** if asked `Are you sure you want to continue connecting (yes/no)?`. +It adds GitLab.com to the known hosts. + +### Configuring Nginx + +Now, let's make sure our web server configuration points to the `current/public` rather than `public`. + +Open the default Nginx server block configuration file by typing: + +```bash +sudo nano /etc/nginx/sites-available/default +``` + +The configuration should be like this. + +``` +server { + root /var/www/app/current/public; + server_name example.com; + # Rest of the configuration +} +``` + +>**Note:** +You may replace the app's name in `/var/www/app/current/public` with the folder name of your application. + +## Setting up Envoy + +So we have our Laravel app ready for production. +The next thing is to use Envoy to perform the deploy. + +To use Envoy, we should first install it on our local machine [using the given instructions by Laravel](https://laravel.com/docs/envoy/#introduction). + +### How Envoy works + +The pros of Envoy is that it doesn't require Blade engine, it just uses Blade syntax to define tasks. +To start, we create an `Envoy.blade.php` in the root of our app with a simple task to test Envoy. + + +```php +@servers(['web' => 'remote_username@remote_host']) + +@task('list', [on => 'web']) + ls -l +@endtask +``` + +As you may expect, we have an array within `@servers` directive at the top of the file, which contains a key named `web` with a value of the server's address (e.g. deployer@192.168.1.1). +Then within our `@task` directive we define the bash commands that should be run on the server when the task is executed. + +On the local machine use the `run` command to run Envoy tasks. + +```bash +envoy run list +``` + +It should execute the `list` task we defined earlier, which connects to the server and lists directory contents. + +Envoy is not a dependency of Laravel, therefore you can use it for any PHP application. + +### Zero downtime deployment + +Every time we deploy to the production server, Envoy downloads the latest release of our app from GitLab repository and replace it with preview's release. +Envoy does this without any [downtime](https://en.wikipedia.org/wiki/Downtime), +so we don't have to worry during the deployment while someone might be reviewing the site. +Our deployment plan is to clone the latest release from GitLab repository, install the Composer dependencies and finally, activate the new release. + +#### @setup directive + +```php +... + +@setup + $repository = 'git@gitlab.example.com:/laravel-sample.git'; + $releases_dir = '/var/www/app/releases'; + $app_dir = '/var/www/app'; + $release = date('YmdHis'); + $new_release_dir = $releases_dir .'/'. $release; +@endsetup + +... +``` + +- `$repository` is the address of our repository +- `$releases_dir` directory is where we deploy the app +- `$app_dir` is the actual location of the app that is live on the server +- `$release` contains a date, so every time that we deploy a new release of our app, we get a new folder with the current date as name +- `$new_release_dir` is the full path of the new release which is used just to make the tasks cleaner + +The first step of our deployment process is to define a set of variables within [@setup](https://laravel.com/docs/envoy/#setup) directive. +You may change the `app` to your application's name. + +#### @story directive + +```php +... + +@story('deploy') + clone_repository + run_composer + update_symlinks +@endstory + +... +``` + +The [@story](https://laravel.com/docs/envoy/#stories) directive allows us define a list of tasks that can be run as a single task. +Here we have three tasks called `clone_repository`, `run_composer`, `update_symlinks`. These variables are usable to making our task's codes more cleaner. + +Let's create these three tasks one by one. + +#### Clone the repository + +The first task will create the `releases` directory (if it doesn't exist), and then clone the `master` branch of the repository (by default) into the new release directory, given by the `$new_release_dir` variable. +The `releases` directory will hold all our deployments: + +```php +... + +@task('clone_repository') + echo 'Cloning repository' + [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} + git clone --depth 1 {{ $repository }} {{ $new_release_dir }} +@endtask + +... +``` + +While our project grows, its Git history will be very very long over time. +Since we are creating a directory for each release, it might not be necessary to have the history of the project downloaded for each release. +The `--depth 1` option is a great solution which saves systems time and disk space as well. + +#### Installing dependencies with Composer + +As you may suppose, this task just navigates to the new release directory and runs Composer to install the application dependencies: + +```php +... + +@task('run_composer') + echo "Starting deployment ({{ $release }})" + cd {{ $new_release_dir }} + composer install --prefer-dist --no-scripts -q -o +@endtask + +... +``` + +#### Activate new release + +Next thing to do after preparing the requirements of our new release, is to remove the storage directory from it and to create two symbolic links to point the application's `storage` directory and `.env` file to the new release. +Then, creating another symbolic link to the new release with the name of `current` placed in the app directory. +The `current` symbolic link always points to the latest release of our app: + +```php +... + +@task('update_symlinks') + echo "Linking storage directory" + rm -rf {{ $new_release_dir }}/storage + ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage + + echo 'Linking .env file' + ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env + + echo 'Linking current release' + ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current +@endtask +``` + +As you see, we use `-nfs` as an option for `ln` command, which says that the `storage`, `.env` and `current` no longer points to the preview's release and will point them to the new release by force (`f` from -nfs means force), which is the case when we are doing multiple deployments. + +### Full script + +The script is ready, but make sure to change the `deployer@192.168.1.1` to your server and also change `/var/www/app` with the directory you want to deploy your app. + +At the end, our `Envoy.blade.php` file will look like this: + +```php +@servers(['web' => 'deployer@192.168.1.1']) + +@setup + $repository = 'git@gitlab.example.com:/laravel-sample.git'; + $releases_dir = '/var/www/app/releases'; + $app_dir = '/var/www/app'; + $release = date('YmdHis'); + $new_release_dir = $releases_dir .'/'. $release; +@endsetup + +@story('deploy') + clone_repository + run_composer + update_symlinks +@endstory + +@task('clone_repository') + echo 'Cloning repository' + [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} + git clone --depth 1 {{ $repository }} {{ $new_release_dir }} +@endtask + +@task('run_composer') + echo "Starting deployment ({{ $release }})" + cd {{ $new_release_dir }} + composer install --prefer-dist --no-scripts -q -o +@endtask + +@task('update_symlinks') + echo "Linking storage directory" + rm -rf {{ $new_release_dir }}/storage + ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage + + echo 'Linking .env file' + ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env + + echo 'Linking current release' + ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current +@endtask +``` + +One more thing we should do before any deployment is to manually copy our application `storage` folder to the `/var/www/app` directory on the server for the first time. +You might want to create another Envoy task to do that for you. +We also create the `.env` file in the same path to setup our production environment variables for Laravel. +These are persistent data and will be shared to every new release. + +Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ce/ci/environments.html), which will be described [later](#setting-up-gitlab-ci) in this tutorial. + +It is time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. +To keep things simple, we commit directly to `master`, without using [feature-branches](../../ee/workflow/gitlab_flow.html/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. +In a real world project, teams may use [Issue Tracker](../../user/project/issues/index.md) and [Merge Requests](../../user/project/merge_requests/index.md) to move their code across branches: + +```bash +git add Envoy.blade.php +git commit -m 'Add Envoy' +git push origin master +``` + +## Continuous Integration with GitLab + +We have our app ready on GitLab, and we also can deploy it manually. +But let's take a step forward to do it automatically with Continuous Delivery method. +We need to check every commit with a set of automated tests to become aware of issues at the earliest, and then, we can deploy to the target environment if we are happy with the result of the tests. + +[GitLab CI](/gitlab-ci/) allows us to use [Docker](https://docker.com/) engine to handle the process of testing and deploying our app. +In the case you're not familiar with Docker, refer to [How to Automate Docker Deployments](http://paislee.io/how-to-automate-docker-deployments/). + +Before setting up GitLab CI, we need to prepare our work environment to be able to build, test, and deploy our app with GitLab CI. +To do that, We'll use a Docker image which has the minimum requirements that a Laravel app needs to run. +[There are other ways](../../ce/ci/examples/php.html/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. + +With Docker images our builds run incredibly faster! + +### Create a Container Image + +Let's create a [Dockerfile](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Dockerfile) in the root directory of our app with the following content: + +```bash +# Set the base image for subsequent instructions +FROM php:7.1 + +# Update packages +RUN apt-get update + +# Install PHP and composer dependencies +RUN apt-get install git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev -yqq + +# Clear out the local repository of retrieved package files +RUN apt-get clean + +# Install needed extensions +# Here you can install any other extension that you need during the test and deployment process +RUN docker-php-ext-install mcrypt pdo_mysql zip + +# Install Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Install Laravel Envoy +RUN composer global require "laravel/envoy=~1.0" +``` + +We added the [official PHP 7.1 Docker image](https://hub.docker.com/r/_/php/), which consist of a minimum installation of Debian Jessie with PHP pre-installed, and works perfectly for our use case. + +We used `docker-php-ext-install` (provided by the official PHP Docker image) to install the PHP extensions we need. + +#### Setting Up GitLab Container Registry + +Now that we have our `Dockerfile` let's build and push it to our [GitLab Container Registry](../ce/user/project/container_registry.html). + +> The registry is the place to store and tag images for later use. Developers may want to maintain their own registry for private, company images, or for throw-away images used only in testing. Using GitLab Container Registry means you don't need to set up and administer yet another service or use a public registry. + +On your GitLab project repository navigate to the **Registry** tab. + +![container registry page empty image](img/container-registry-page-empty-image.png) + +You may need to enable container registry (under project's settings) to your project to see this tab. +![container registry checkbox](img/container-registry-checkbox.png) + +To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password. + +```bash +docker login registry.gitlab.com +``` +Then we can build and push our image to GitLab: + +```bash +docker build -t registry.gitlab.com//laravel-sample . + +docker push registry.gitlab.com//laravel-sample +``` + +>**Note:** +To run the above commands, we first need to have [Docker](https://docs.docker.com/engine/installation/) installed on our machine. + +Congratulations! You just pushed the first Docker image to the GitLab registry, and if you refresh the page you should be able to see it. + +![container registry page with image](img/container-registry-page-with-image.png) + +>**Note:** +You can also [use GitLab CI](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine! + +We'll use this image further down in the `.gitlab-ci.yml` config file to handle the process of testing and deploying our app. + +Let's commit the `Dockerfile` file. + +```bash +git add Dockerfile +git commit -m 'Add Dockerfile' +git push origin master +``` + +### Setting up GitLab CI + +In order to build and test our app with GitLab CI, we need a file called `.gitlab-ci.yml` in our repository's root. It is similar to Circle CI and Travis CI, but built in GitLab. + +```yaml +image: registry.gitlab.com//laravel-sample:latest + +services: + - mysql:5.7 + +variables: + MYSQL_DATABASE: homestead + MYSQL_ROOT_PASSWORD: secret + +stages: + - test + - deploy + +unit_test: + stage: test + script: + - composer install + - cp .env.example .env + - php artisan key:generate + - php artisan migrate + - vendor/bin/phpunit + +deploy_production: + stage: deploy + script: + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_PRIVATE_KEY") + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + + - ~/.composer/vendor/bin/envoy run deploy + environment: + name: production + url: http://192.168.1.1 + when: manual + only: + - master +``` + +That's a lot to take in, isn't it? Let's run through it step by step. + +#### Image and Services + +[GitLab Runners](../ee/ci/runners/README.html) run the script defined by .gitlab-ci.yml. +The `image` keyword tells the Runners which image to use. +The `services` keyword defines additional images [that are linked to the main image](../ce/ci/docker/using_docker_images.html/#what-is-a-service). +Here we use the container image we created before as our main image and also use MySQL 5.7 as a service. + +```yaml +image: registry.gitlab.com//laravel-sample:latest + +services: + - mysql:5.7 + +... +``` + +>**Note:** +If you wish to test your app with different PHP versions and [database management systems](../ee/ci/services/README.html), you can define different `image` and `services` keywords for each test job. + +#### Variables + +GitLab CI allows us to use [environment variables](../ce/ci/yaml/#variables) in our jobs. +We defined MySQL as our database management system, which comes with a superuser root, created by default. +So we just should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. +Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). + +```yaml +... + +variables: + MYSQL_DATABASE: homestead + MYSQL_ROOT_PASSWORD: secret + +... +``` + +Clone the `.env.example` file to `.env.testing` from your root repository and set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`. Make sure to set the `APP_KEY` for `.env.testing` as well. This file will override values from the `.env` file when running PHPUnit tests or executing Artisan commands with the `--env=testing option`. + +We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.html/#how-services-are-linked-to-the-build). + +#### Unit Test as the first job + +We defined the required shell scripts as an array of the [script](../ce/ci/yaml/#script) variable to be executed when running `unit_test` job. + +These scripts are some Artisan commands to prepare the Laravel, and, at the end of the script, we'll run the tests by `PHPUnit`. + +```yaml +... + +unit_test: + script: + # Install app dependencies + - composer install + # Setup .env + - cp .env.example .env + # Generate an environment key + - php artisan key:generate + # Run migrations + - php artisan migrate + # Run tests + - vendor/bin/phpunit + +... +``` + +#### Deploy Production + +The job `deploy_production` will deploy the app to the production server. +To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../ce/ci/ssh_keys/README.html/#ssh-keys-when-using-the-docker-executor). +If the SSH keys have added successfully, we can run Envoy. + +GitLab CI supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) as well. +The [environment](../ce/ci/yaml/#environment) keyword tells GitLab that this job deploys to the `production` environment. +The `url` keyword is used to generate a link to our application on the GitLab Environments page. +The `only` keyword tells GitLab CI that the job should be executed only when the pipeline is building the `master` branch. +Lastly, `when: manual` is used to turn the job from running automatically to a manual action. + +```yaml +... + +deploy_production: + script: + # Add the private SSH key to the build environment + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_PRIVATE_KEY") + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + + # Run Envoy + - ~/.composer/vendor/bin/envoy run deploy + + environment: + name: production + url: http://192.168.1.1 + when: manual + only: + - master +``` + +You may also want to add another job for [staging environment](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments), to final test your application before deploying to production. + +### Turn on GitLab CI + +We have prepared everything we need to test and deploy our app with GitLab CI. +To do that, commit and push `.gitlab-ci.yml` to the `master` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**. + +![pipelines page](img/pipelines-page.png) + +Here we see our **Test** and **Deploy** stages. +The **Test** stage has the `unit_test` build running. +click on it to see the Runner's output. + +![pipeline page](img/pipeline_page.png) + +After our code passed through the pipeline successfully, we can deploy to our production server by clicking the **play** button on the right side. + +![pipelines page deploy button](img/pipelines_page_deploy_button.png) + +Once the deploy pipeline passed successfully, navigate to **Pipelines > Environments**. + +![environments page](img/environments_page.png) + +If something doesn't work as expected, you can roll back to the latest working version of your app. + +![environment page](img/environment_page.png) + +By clicking on the external link icon specified on the right side, GitLab opens the production website. +Our deployment successfully was done and we can see the application is live. + +![laravel welcome page](img/laravel_welcome_page.png) + +In the case that you're interested to know how is the application directory structure on the production server after deployment, here are three directories named `current`, `releases` and `storage`. +As you know, the `current` directory is a symbolic link that points to the latest release. +The `.env` file consists of our Laravel environment variables. + + +![production server app directory](img/production_server_app_directory.png) + +If you navigate to the `current` directory, you should see the application's content. +As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `storage` is pointing to the `/var/www/app/storage/` directory. + +![production server current directory](img/production_server_current_directory.png) + +## Conclusion + +We configured GitLab CI to perform automated tests and used the method of [Continuous delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. +Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. + +## About guest author +Mehran is a web developer writing applications with PHP, Javascript. Recently interested in learning swift. \ No newline at end of file -- cgit v1.2.1 From 30499181974418bb780b619803c495e2837d5dde Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 30 Aug 2017 15:10:33 -0300 Subject: copyedit --- doc/articles/index.md | 1 + .../.gitkeep | 0 .../img/.gitkeep | 0 .../img/container-registry-page-empty-image.png | Bin 22449 -> 0 bytes .../img/container_registry_page_empty_image.png | Bin 0 -> 22449 bytes .../img/deploy-keys-page.png | Bin 54281 -> 0 bytes .../img/deploy_keys_page.png | Bin 0 -> 54281 bytes .../img/laravel-welcome-page.png | Bin 5785 -> 0 bytes .../img/laravel_welcome_page.png | Bin 0 -> 5785 bytes .../img/production-server-app-directory.png | Bin 11082 -> 0 bytes .../img/production-server-current-directory.png | Bin 21993 -> 0 bytes .../img/production_server_app_directory.png | Bin 0 -> 11082 bytes .../img/production_server_current_directory.png | Bin 0 -> 21993 bytes .../img/secret-variables-page.png | Bin 33815 -> 0 bytes .../img/secret_variables_page.png | Bin 0 -> 33815 bytes .../index.md | 10 +++++----- 16 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 4b0c85b9272..0dcfcc5703a 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,6 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | +| [How to test and deploy Laravel/PHP applications with GitLab CI and Envoy](test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md) | Tutorial | 2017-08-31 | | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png deleted file mode 100644 index 1f52e1afe83..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container-registry-page-empty-image.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png new file mode 100644 index 00000000000..1f52e1afe83 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png deleted file mode 100644 index d0ce425fbf4..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy-keys-page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png new file mode 100644 index 00000000000..d0ce425fbf4 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png deleted file mode 100644 index 3bb21fd12b4..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel-welcome-page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png new file mode 100644 index 00000000000..3bb21fd12b4 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png deleted file mode 100644 index 6dbc29fc25c..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-app-directory.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png deleted file mode 100644 index 8a6dcccfa38..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production-server-current-directory.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png new file mode 100644 index 00000000000..6dbc29fc25c Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png new file mode 100644 index 00000000000..8a6dcccfa38 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png deleted file mode 100644 index 3249ff9d4e6..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret-variables-page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png new file mode 100644 index 00000000000..3249ff9d4e6 Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index 475123a44a0..ba1d5499721 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -1,4 +1,4 @@ -# Test and deploy Laravel applications with GitLab CI and Envoy +# Test and deploy Laravel applications with GitLab CI/CD and Envoy > **Type:** tutorial || > **Level:** intermediary || @@ -437,10 +437,10 @@ Now that we have our `Dockerfile` let's build and push it to our [GitLab Contain On your GitLab project repository navigate to the **Registry** tab. -![container registry page empty image](img/container-registry-page-empty-image.png) +![container registry page empty image](img/container_registry_page_empty_image.png) You may need to enable container registry (under project's settings) to your project to see this tab. -![container registry checkbox](img/container-registry-checkbox.png) +![container registry checkbox](img/container_registry_checkbox.png) To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password. @@ -460,7 +460,7 @@ To run the above commands, we first need to have [Docker](https://docs.docker.co Congratulations! You just pushed the first Docker image to the GitLab registry, and if you refresh the page you should be able to see it. -![container registry page with image](img/container-registry-page-with-image.png) +![container registry page with image](img/container_registry_page_with_image.png) >**Note:** You can also [use GitLab CI](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine! @@ -629,7 +629,7 @@ You may also want to add another job for [staging environment](https://about.git We have prepared everything we need to test and deploy our app with GitLab CI. To do that, commit and push `.gitlab-ci.yml` to the `master` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**. -![pipelines page](img/pipelines-page.png) +![pipelines page](img/pipelines_page.png) Here we see our **Test** and **Deploy** stages. The **Test** stage has the `unit_test` build running. -- cgit v1.2.1 From 5b574ac90aa8635548fed393d08ca09c30f33a34 Mon Sep 17 00:00:00 2001 From: Mehran Rasulian Date: Thu, 31 Aug 2017 12:14:26 +0000 Subject: Update index.md --- .../index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index ba1d5499721..cbfe2bf759d 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -488,6 +488,8 @@ services: variables: MYSQL_DATABASE: homestead MYSQL_ROOT_PASSWORD: secret + DB_HOST: mysql + DB_USERNAME: root stages: - test @@ -548,20 +550,21 @@ We defined MySQL as our database management system, which comes with a superuser So we just should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). +Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are the Laravel specific variables. +We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.html/#how-services-are-linked-to-the-build). + ```yaml ... variables: MYSQL_DATABASE: homestead MYSQL_ROOT_PASSWORD: secret + DB_HOST: mysql + DB_USERNAME: root ... ``` -Clone the `.env.example` file to `.env.testing` from your root repository and set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`. Make sure to set the `APP_KEY` for `.env.testing` as well. This file will override values from the `.env` file when running PHPUnit tests or executing Artisan commands with the `--env=testing option`. - -We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.html/#how-services-are-linked-to-the-build). - #### Unit Test as the first job We defined the required shell scripts as an array of the [script](../ce/ci/yaml/#script) variable to be executed when running `unit_test` job. @@ -669,7 +672,4 @@ As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `sto ## Conclusion We configured GitLab CI to perform automated tests and used the method of [Continuous delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. -Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. - -## About guest author -Mehran is a web developer writing applications with PHP, Javascript. Recently interested in learning swift. \ No newline at end of file +Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. \ No newline at end of file -- cgit v1.2.1 From 61c6b2bbf697ac55c4734cd4625d871e633c2baf Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 09:56:31 -0300 Subject: copyedit --- doc/articles/index.md | 2 +- .../index.md | 113 +++++++++++---------- 2 files changed, 60 insertions(+), 55 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 0dcfcc5703a..5604f52bd94 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,7 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [How to test and deploy Laravel/PHP applications with GitLab CI and Envoy](test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md) | Tutorial | 2017-08-31 | +| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md) | Tutorial | 2017-08-31 | | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index cbfe2bf759d..507a6493f0a 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -3,13 +3,13 @@ > **Type:** tutorial || > **Level:** intermediary || > **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || -> **Publication date:** 2017/06/14 +> **Publication date:** 2017-08-31 ## Introduction -GitLab features our applications with Continuous Integration, and it is possible to deploy the new code changes to the production server whenever we want just by clicking a button! +GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. -In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI](/gitlab-ci/) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). +In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../../ci/README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). We assume you have a basic experience with Laravel, Linux servers, and you know how to use GitLab. @@ -18,17 +18,16 @@ Laravel is a high quality web framework written in PHP. It has a great community with a [fantastic documentation](https://laravel.com/docs). Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others. -We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner which is based on PHP. -It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers. -Those tasks can be cloning your project from the repository, installing the Composer dependencies, running [Artisan commands](https://laravel.com/docs/artisan) and more. +We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner based on PHP. +It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan). ## Initialize our Laravel app on GitLab -We assume [you have installed a new laravel project](https://laravel.com/docs/installation#installation), so we start with writing a unit test, and initialize the git for the project. +We assume [you have installed a new laravel project](https://laravel.com/docs/installation#installation), so let's start with a unit test, and initialize Git for the project. ### Unit Test -Every new installation of Laravel (currently 5.4) comes with two type of tests 'Feature' and 'Unit' placed in the tests directory. +Every new installation of Laravel (currently 5.4) comes with two type of tests, 'Feature' and 'Unit', placed in the tests directory. Here's a unit test from `test/Unit/ExampleTest.php`: ```php @@ -47,23 +46,23 @@ class ExampleTest extends TestCase } ``` -This test is as simple as asserting that the given value is true! +This test is as simple as asserting that the given value is true. Laravel uses `PHPUnit` for tests by default. -If we run `vendor/bin/phpunit` we should see green! +If we run `vendor/bin/phpunit` we should see the green output: ```bash vendor/bin/phpunit OK (1 test, 1 assertions) ``` -This test will be used later for continuously testing our app with GitLab CI. +This test will be used later for continuously testing our app with GitLab CI/CD. ### Push to GitLab Since we have our app up and running locally, it's time to push the codebase to our remote repository. Let's create [a new project](https://docs.gitlab.com/ee/gitlab-basics/create-project.html) in GitLab named `laravel-sample`. -After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and do the first commit. +After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and push the first commit. ```bash @@ -77,7 +76,7 @@ git push -u origin master ## Configure the production server -Before we begin setting up Envoy and GitLab CI, let's quickly make sure the production server is ready for deployment. +Before we begin setting up Envoy and GitLab CI/CD, let's quickly make sure the production server is ready for deployment. We have installed LEMP stack which stands for Linux, Nginx, MySQL and PHP on our Ubuntu 16.04. ### Create a new user @@ -113,9 +112,9 @@ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys cat ~/.ssh/id_rsa ``` -Now, add it to your GitLab project as a [secret variable](../../ci/variables/README.html#secret-variables). +Now, let's add it to your GitLab project as a [secret variable](../../ci/variables/README.html#secret-variables). Secret variables are user-defined variables and are stored out of `.gitlab-ci.yml`, for security purposes. -They can be added per project by navigating to **Project** > **Settings** > **CI/CD Pipelines**. +They can be added per project by navigating to the project's **Settings** > **CI/CD**. ![secret variables page](img/secret_variables_page.png) @@ -192,7 +191,7 @@ To start, we create an `Envoy.blade.php` in the root of our app with a simple ta @endtask ``` -As you may expect, we have an array within `@servers` directive at the top of the file, which contains a key named `web` with a value of the server's address (e.g. deployer@192.168.1.1). +As you may expect, we have an array within `@servers` directive at the top of the file, which contains a key named `web` with a value of the server's address (e.g. `deployer@192.168.1.1`). Then within our `@task` directive we define the bash commands that should be run on the server when the task is executed. On the local machine use the `run` command to run Envoy tasks. @@ -214,6 +213,10 @@ Our deployment plan is to clone the latest release from GitLab repository, insta #### @setup directive +The first step of our deployment process is to define a set of variables within [@setup](https://laravel.com/docs/envoy/#setup) directive. +You may change the `app` to your application's name: + + ```php ... @@ -234,11 +237,12 @@ Our deployment plan is to clone the latest release from GitLab repository, insta - `$release` contains a date, so every time that we deploy a new release of our app, we get a new folder with the current date as name - `$new_release_dir` is the full path of the new release which is used just to make the tasks cleaner -The first step of our deployment process is to define a set of variables within [@setup](https://laravel.com/docs/envoy/#setup) directive. -You may change the `app` to your application's name. - #### @story directive +The [@story](https://laravel.com/docs/envoy/#stories) directive allows us define a list of tasks that can be run as a single task. +Here we have three tasks called `clone_repository`, `run_composer`, `update_symlinks`. These variables are usable to making our task's codes more cleaner: + + ```php ... @@ -251,9 +255,6 @@ You may change the `app` to your application's name. ... ``` -The [@story](https://laravel.com/docs/envoy/#stories) directive allows us define a list of tasks that can be run as a single task. -Here we have three tasks called `clone_repository`, `run_composer`, `update_symlinks`. These variables are usable to making our task's codes more cleaner. - Let's create these three tasks one by one. #### Clone the repository @@ -274,12 +275,12 @@ The `releases` directory will hold all our deployments: ``` While our project grows, its Git history will be very very long over time. -Since we are creating a directory for each release, it might not be necessary to have the history of the project downloaded for each release. +Since we are creating a directory per release, it might not be necessary to have the history of the project downloaded for each release. The `--depth 1` option is a great solution which saves systems time and disk space as well. #### Installing dependencies with Composer -As you may suppose, this task just navigates to the new release directory and runs Composer to install the application dependencies: +As you may know, this task just navigates to the new release directory and runs Composer to install the application dependencies: ```php ... @@ -296,7 +297,7 @@ As you may suppose, this task just navigates to the new release directory and ru #### Activate new release Next thing to do after preparing the requirements of our new release, is to remove the storage directory from it and to create two symbolic links to point the application's `storage` directory and `.env` file to the new release. -Then, creating another symbolic link to the new release with the name of `current` placed in the app directory. +Then, we need to create another symbolic link to the new release with the name of `current` placed in the app directory. The `current` symbolic link always points to the latest release of our app: ```php @@ -315,7 +316,7 @@ The `current` symbolic link always points to the latest release of our app: @endtask ``` -As you see, we use `-nfs` as an option for `ln` command, which says that the `storage`, `.env` and `current` no longer points to the preview's release and will point them to the new release by force (`f` from -nfs means force), which is the case when we are doing multiple deployments. +As you see, we use `-nfs` as an option for `ln` command, which says that the `storage`, `.env` and `current` no longer points to the preview's release and will point them to the new release by force (`f` from `-nfs` means force), which is the case when we are doing multiple deployments. ### Full script @@ -372,7 +373,7 @@ These are persistent data and will be shared to every new release. Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ce/ci/environments.html), which will be described [later](#setting-up-gitlab-ci) in this tutorial. -It is time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. +Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. To keep things simple, we commit directly to `master`, without using [feature-branches](../../ee/workflow/gitlab_flow.html/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. In a real world project, teams may use [Issue Tracker](../../user/project/issues/index.md) and [Merge Requests](../../user/project/merge_requests/index.md) to move their code across branches: @@ -385,14 +386,14 @@ git push origin master ## Continuous Integration with GitLab We have our app ready on GitLab, and we also can deploy it manually. -But let's take a step forward to do it automatically with Continuous Delivery method. +But let's take a step forward to do it automatically with [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) method. We need to check every commit with a set of automated tests to become aware of issues at the earliest, and then, we can deploy to the target environment if we are happy with the result of the tests. -[GitLab CI](/gitlab-ci/) allows us to use [Docker](https://docker.com/) engine to handle the process of testing and deploying our app. +[GitLab CI/CD](../../ci/README.md) allows us to use [Docker](https://docker.com/) engine to handle the process of testing and deploying our app. In the case you're not familiar with Docker, refer to [How to Automate Docker Deployments](http://paislee.io/how-to-automate-docker-deployments/). -Before setting up GitLab CI, we need to prepare our work environment to be able to build, test, and deploy our app with GitLab CI. -To do that, We'll use a Docker image which has the minimum requirements that a Laravel app needs to run. +To be able to build, test, and deploy our app with GitLab CI/CD, we need to prepare our work environment. +To do that, we'll use a Docker image which has the minimum requirements that a Laravel app needs to run. [There are other ways](../../ce/ci/examples/php.html/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. With Docker images our builds run incredibly faster! @@ -439,10 +440,11 @@ On your GitLab project repository navigate to the **Registry** tab. ![container registry page empty image](img/container_registry_page_empty_image.png) -You may need to enable container registry (under project's settings) to your project to see this tab. +You may need to [enable Container Registry](../../user/project/container_registry.md#enable-the-container-registry-for-your-project) to your project to see this tab. You'll find it under your project's **Settings > General > Sharing and permissions**. + ![container registry checkbox](img/container_registry_checkbox.png) -To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password. +To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password: ```bash docker login registry.gitlab.com @@ -458,14 +460,14 @@ docker push registry.gitlab.com//laravel-sample >**Note:** To run the above commands, we first need to have [Docker](https://docs.docker.com/engine/installation/) installed on our machine. -Congratulations! You just pushed the first Docker image to the GitLab registry, and if you refresh the page you should be able to see it. +Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it: ![container registry page with image](img/container_registry_page_with_image.png) >**Note:** -You can also [use GitLab CI](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine! +You can also [use GitLab CI/CD](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine. -We'll use this image further down in the `.gitlab-ci.yml` config file to handle the process of testing and deploying our app. +We'll use this image further down in the `.gitlab-ci.yml` configuration file to handle the process of testing and deploying our app. Let's commit the `Dockerfile` file. @@ -475,9 +477,11 @@ git commit -m 'Add Dockerfile' git push origin master ``` -### Setting up GitLab CI +### Setting up GitLab CI/CD + +In order to build and test our app with GitLab CI/CD, we need a file called `.gitlab-ci.yml` in our repository's root. It is similar to Circle CI and Travis CI, but built-in GitLab. -In order to build and test our app with GitLab CI, we need a file called `.gitlab-ci.yml` in our repository's root. It is similar to Circle CI and Travis CI, but built in GitLab. +Our `.gitlab-ci.yml` file will look like this: ```yaml image: registry.gitlab.com//laravel-sample:latest @@ -526,9 +530,9 @@ That's a lot to take in, isn't it? Let's run through it step by step. #### Image and Services -[GitLab Runners](../ee/ci/runners/README.html) run the script defined by .gitlab-ci.yml. +[GitLab Runners](../ee/ci/runners/README.md) run the script defined by `.gitlab-ci.yml`. The `image` keyword tells the Runners which image to use. -The `services` keyword defines additional images [that are linked to the main image](../ce/ci/docker/using_docker_images.html/#what-is-a-service). +The `services` keyword defines additional images [that are linked to the main image](../ce/ci/docker/using_docker_images.md/#what-is-a-service). Here we use the container image we created before as our main image and also use MySQL 5.7 as a service. ```yaml @@ -541,17 +545,18 @@ services: ``` >**Note:** -If you wish to test your app with different PHP versions and [database management systems](../ee/ci/services/README.html), you can define different `image` and `services` keywords for each test job. +If you wish to test your app with different PHP versions and [database management systems](../ee/ci/services/README.md), you can define different `image` and `services` keywords for each test job. #### Variables -GitLab CI allows us to use [environment variables](../ce/ci/yaml/#variables) in our jobs. -We defined MySQL as our database management system, which comes with a superuser root, created by default. -So we just should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. +GitLab CI/CD allows us to use [environment variables](../ce/ci/yaml/#variables) in our jobs. +We defined MySQL as our database management system, which comes with a superuser root created by default. + +So we should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). -Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are the Laravel specific variables. -We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.html/#how-services-are-linked-to-the-build). +Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are Laravel specific variables. +We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.md/#how-services-are-linked-to-the-build). ```yaml ... @@ -590,13 +595,13 @@ unit_test: ... ``` -#### Deploy Production +#### Deploy to production The job `deploy_production` will deploy the app to the production server. -To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../ce/ci/ssh_keys/README.html/#ssh-keys-when-using-the-docker-executor). +To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../ce/ci/ssh_keys/README.md/#ssh-keys-when-using-the-docker-executor). If the SSH keys have added successfully, we can run Envoy. -GitLab CI supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) as well. +As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well. The [environment](../ce/ci/yaml/#environment) keyword tells GitLab that this job deploys to the `production` environment. The `url` keyword is used to generate a link to our application on the GitLab Environments page. The `only` keyword tells GitLab CI that the job should be executed only when the pipeline is building the `master` branch. @@ -627,9 +632,9 @@ deploy_production: You may also want to add another job for [staging environment](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments), to final test your application before deploying to production. -### Turn on GitLab CI +### Turn on GitLab CI/CD -We have prepared everything we need to test and deploy our app with GitLab CI. +We have prepared everything we need to test and deploy our app with GitLab CI/CD. To do that, commit and push `.gitlab-ci.yml` to the `master` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**. ![pipelines page](img/pipelines_page.png) @@ -661,7 +666,6 @@ In the case that you're interested to know how is the application directory stru As you know, the `current` directory is a symbolic link that points to the latest release. The `.env` file consists of our Laravel environment variables. - ![production server app directory](img/production_server_app_directory.png) If you navigate to the `current` directory, you should see the application's content. @@ -671,5 +675,6 @@ As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `sto ## Conclusion -We configured GitLab CI to perform automated tests and used the method of [Continuous delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. -Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. \ No newline at end of file +We configured GitLab CI to perform automated tests and used the method of [Continuous Delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. + +Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. -- cgit v1.2.1 From d6f88d229506be03f293e24e1f747cd91c75171f Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 10:15:15 -0300 Subject: fixes broken links --- .../index.md | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index 507a6493f0a..9d471f0ee86 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -9,7 +9,7 @@ GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. -In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../../ci/README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). +In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../../ci/README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). We assume you have a basic experience with Laravel, Linux servers, and you know how to use GitLab. @@ -61,7 +61,7 @@ This test will be used later for continuously testing our app with GitLab CI/CD. ### Push to GitLab Since we have our app up and running locally, it's time to push the codebase to our remote repository. -Let's create [a new project](https://docs.gitlab.com/ee/gitlab-basics/create-project.html) in GitLab named `laravel-sample`. +Let's create [a new project](../../gitlab-basics/create-project.md) in GitLab named `laravel-sample`. After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and push the first commit. @@ -112,7 +112,7 @@ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys cat ~/.ssh/id_rsa ``` -Now, let's add it to your GitLab project as a [secret variable](../../ci/variables/README.html#secret-variables). +Now, let's add it to your GitLab project as a [secret variable](../../ci/variables/README.md#secret-variables). Secret variables are user-defined variables and are stored out of `.gitlab-ci.yml`, for security purposes. They can be added per project by navigating to the project's **Settings** > **CI/CD**. @@ -121,7 +121,7 @@ They can be added per project by navigating to the project's **Settings** > **CI To the field **KEY**, add the name `SSH_PRIVATE_KEY`, and to the **VALUE** field, paste the private key you've copied earlier. We'll use this variable in the `.gitlab-ci.yml` later, to easily connect to our remote server as the deployer user without entering its password. -We also need to add the public key to **Project** > **Settings** > **Repository** as [Deploy Keys](../../ce/ssh/README.html/#deploy-keys), which gives us the ability to access our repository from the server through [SSH protocol](../../ee/gitlab-basics/command-line-commands.html/#start-working-on-your-project). +We also need to add the public key to **Project** > **Settings** > **Repository** as [Deploy Keys](../../ssh/README.md/#deploy-keys), which gives us the ability to access our repository from the server through [SSH protocol](../../gitlab-basics/command-line-commands.md/#start-working-on-your-project). ```bash @@ -371,10 +371,10 @@ You might want to create another Envoy task to do that for you. We also create the `.env` file in the same path to setup our production environment variables for Laravel. These are persistent data and will be shared to every new release. -Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ce/ci/environments.html), which will be described [later](#setting-up-gitlab-ci) in this tutorial. +Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ci/environments.md), which will be described [later](#setting-up-gitlab-ci-cd) in this tutorial. Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. -To keep things simple, we commit directly to `master`, without using [feature-branches](../../ee/workflow/gitlab_flow.html/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. +To keep things simple, we commit directly to `master`, without using [feature-branches](../../workflow/gitlab_flow.md/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. In a real world project, teams may use [Issue Tracker](../../user/project/issues/index.md) and [Merge Requests](../../user/project/merge_requests/index.md) to move their code across branches: ```bash @@ -394,7 +394,7 @@ In the case you're not familiar with Docker, refer to [How to Automate Docker De To be able to build, test, and deploy our app with GitLab CI/CD, we need to prepare our work environment. To do that, we'll use a Docker image which has the minimum requirements that a Laravel app needs to run. -[There are other ways](../../ce/ci/examples/php.html/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. +[There are other ways](../../ci/examples/php.md/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. With Docker images our builds run incredibly faster! @@ -432,7 +432,7 @@ We used `docker-php-ext-install` (provided by the official PHP Docker image) to #### Setting Up GitLab Container Registry -Now that we have our `Dockerfile` let's build and push it to our [GitLab Container Registry](../ce/user/project/container_registry.html). +Now that we have our `Dockerfile` let's build and push it to our [GitLab Container Registry](../../user/project/container_registry.md). > The registry is the place to store and tag images for later use. Developers may want to maintain their own registry for private, company images, or for throw-away images used only in testing. Using GitLab Container Registry means you don't need to set up and administer yet another service or use a public registry. @@ -462,7 +462,7 @@ To run the above commands, we first need to have [Docker](https://docs.docker.co Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it: -![container registry page with image](img/container_registry_page_with_image.png) +![container registry page with image](img/container_registry_page_empty_image.png) >**Note:** You can also [use GitLab CI/CD](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine. @@ -530,9 +530,9 @@ That's a lot to take in, isn't it? Let's run through it step by step. #### Image and Services -[GitLab Runners](../ee/ci/runners/README.md) run the script defined by `.gitlab-ci.yml`. +[GitLab Runners](../../ci/runners/README.md) run the script defined by `.gitlab-ci.yml`. The `image` keyword tells the Runners which image to use. -The `services` keyword defines additional images [that are linked to the main image](../ce/ci/docker/using_docker_images.md/#what-is-a-service). +The `services` keyword defines additional images [that are linked to the main image](../../ci/docker/using_docker_images.md/#what-is-a-service). Here we use the container image we created before as our main image and also use MySQL 5.7 as a service. ```yaml @@ -545,18 +545,18 @@ services: ``` >**Note:** -If you wish to test your app with different PHP versions and [database management systems](../ee/ci/services/README.md), you can define different `image` and `services` keywords for each test job. +If you wish to test your app with different PHP versions and [database management systems](../../ci/services/README.md), you can define different `image` and `services` keywords for each test job. #### Variables -GitLab CI/CD allows us to use [environment variables](../ce/ci/yaml/#variables) in our jobs. +GitLab CI/CD allows us to use [environment variables](../../ci/yaml/README.md#variables) in our jobs. We defined MySQL as our database management system, which comes with a superuser root created by default. So we should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are Laravel specific variables. -We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../ce/ci/docker/using_docker_images.md/#how-services-are-linked-to-the-build). +We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../../ci/docker/using_docker_images.md/#how-services-are-linked-to-the-build). ```yaml ... @@ -572,7 +572,7 @@ variables: #### Unit Test as the first job -We defined the required shell scripts as an array of the [script](../ce/ci/yaml/#script) variable to be executed when running `unit_test` job. +We defined the required shell scripts as an array of the [script](../../ci/yaml/README.md#script) variable to be executed when running `unit_test` job. These scripts are some Artisan commands to prepare the Laravel, and, at the end of the script, we'll run the tests by `PHPUnit`. @@ -598,11 +598,11 @@ unit_test: #### Deploy to production The job `deploy_production` will deploy the app to the production server. -To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../ce/ci/ssh_keys/README.md/#ssh-keys-when-using-the-docker-executor). +To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ci/ssh_keys/README.md/#ssh-keys-when-using-the-docker-executor). If the SSH keys have added successfully, we can run Envoy. As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well. -The [environment](../ce/ci/yaml/#environment) keyword tells GitLab that this job deploys to the `production` environment. +The [environment](../../ci/yaml/README.md#environment) keyword tells GitLab that this job deploys to the `production` environment. The `url` keyword is used to generate a link to our application on the GitLab Environments page. The `only` keyword tells GitLab CI that the job should be executed only when the pipeline is building the `master` branch. Lastly, `when: manual` is used to turn the job from running automatically to a manual action. -- cgit v1.2.1 From 70317b76e484c8fb9b0cbcc9055167bf3670b93d Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 10:58:09 -0300 Subject: replace blurred images --- .../img/container_registry_page_empty_image.png | Bin 22449 -> 56091 bytes .../img/deploy_keys_page.png | Bin 54281 -> 292969 bytes .../img/environment_page.png | Bin 82411 -> 185393 bytes .../img/environments_page.png | Bin 61335 -> 134742 bytes .../img/pipeline_page.png | Bin 75901 -> 172664 bytes .../img/pipelines_page.png | Bin 52963 -> 119955 bytes .../img/pipelines_page_deploy_button.png | Bin 62798 -> 141393 bytes .../img/secret_variables_page.png | Bin 33815 -> 233764 bytes 8 files changed, 0 insertions(+), 0 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png index 1f52e1afe83..b1406fed6b8 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png index d0ce425fbf4..d62e5494b8c 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png index 1eff36cc859..a06b6d417cd 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png index 23ce3ee05e7..d357ecda7d2 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png index 503d22f489d..baf8dec499c 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png index 651ea0f00dc..d96c43bcf16 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png index 35300963de6..997db10189f 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png index 3249ff9d4e6..658c0b5bcac 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png differ -- cgit v1.2.1 From 1016b23efc13ac095c8ca13937c16b97abee1639 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 12:26:02 -0300 Subject: add img, fix link --- .../img/deploy_keys_page.png | Bin 292969 -> 339666 bytes .../index.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png index d62e5494b8c..9aae11b8679 100644 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index 9d471f0ee86..e0cdf441576 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -462,7 +462,7 @@ To run the above commands, we first need to have [Docker](https://docs.docker.co Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it: -![container registry page with image](img/container_registry_page_empty_image.png) +![container registry page with image](img/container_registry_page_with_image.jpg) >**Note:** You can also [use GitLab CI/CD](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine. -- cgit v1.2.1 From abcdbe2d5e0e30b1cb158633af2821b111a8980a Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 12:37:09 -0300 Subject: fixes docs lint --- .../test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index e0cdf441576..946f20c5f18 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -420,7 +420,7 @@ RUN apt-get clean RUN docker-php-ext-install mcrypt pdo_mysql zip # Install Composer -RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer +RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # Install Laravel Envoy RUN composer global require "laravel/envoy=~1.0" -- cgit v1.2.1 From 4ce10fda963579d395881710ff1ae8713f5f2782 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 31 Aug 2017 17:49:33 +0200 Subject: Move apt-get quiet flag in the beginning --- .../test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md index 946f20c5f18..18e42d9f52a 100644 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md @@ -410,7 +410,7 @@ FROM php:7.1 RUN apt-get update # Install PHP and composer dependencies -RUN apt-get install git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev -yqq +RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev # Clear out the local repository of retrieved package files RUN apt-get clean -- cgit v1.2.1 From c751448dd1023ef783361757f01b179bc3bd02ed Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 13:01:45 -0300 Subject: add image --- .../img/container_registry_page_with_image.jpg | Bin 0 -> 93531 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg (limited to 'doc/articles') diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg new file mode 100644 index 00000000000..d1f0cbc08ab Binary files /dev/null and b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg differ -- cgit v1.2.1 From ad64668b5767b2f2e6e512aa259ac5fd92df7d6c Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 13:12:59 -0300 Subject: reduce the dir name --- doc/articles/index.md | 2 +- .../img/container_registry_checkbox.png | Bin 0 -> 4730 bytes .../img/container_registry_page_empty_image.png | Bin 0 -> 56091 bytes .../img/container_registry_page_with_image.jpg | Bin 0 -> 93531 bytes .../img/deploy_keys_page.png | Bin 0 -> 339666 bytes .../img/environment_page.png | Bin 0 -> 185393 bytes .../img/environments_page.png | Bin 0 -> 134742 bytes .../img/laravel_welcome_page.png | Bin 0 -> 5785 bytes .../img/pipeline_page.png | Bin 0 -> 172664 bytes .../img/pipelines_page.png | Bin 0 -> 119955 bytes .../img/pipelines_page_deploy_button.png | Bin 0 -> 141393 bytes .../img/production_server_app_directory.png | Bin 0 -> 11082 bytes .../img/production_server_current_directory.png | Bin 0 -> 21993 bytes .../img/secret_variables_page.png | Bin 0 -> 233764 bytes ...ravel_applications_with_gitlab_ci_and_envoy.png | Bin 0 -> 177704 bytes .../laravel_with_gitlab_and_envoy/index.md | 680 +++++++++++++++++++++ .../img/container_registry_checkbox.png | Bin 4730 -> 0 bytes .../img/container_registry_page_empty_image.png | Bin 56091 -> 0 bytes .../img/container_registry_page_with_image.jpg | Bin 93531 -> 0 bytes .../img/deploy_keys_page.png | Bin 339666 -> 0 bytes .../img/environment_page.png | Bin 185393 -> 0 bytes .../img/environments_page.png | Bin 134742 -> 0 bytes .../img/laravel_welcome_page.png | Bin 5785 -> 0 bytes .../img/pipeline_page.png | Bin 172664 -> 0 bytes .../img/pipelines_page.png | Bin 119955 -> 0 bytes .../img/pipelines_page_deploy_button.png | Bin 141393 -> 0 bytes .../img/production_server_app_directory.png | Bin 11082 -> 0 bytes .../img/production_server_current_directory.png | Bin 21993 -> 0 bytes .../img/secret_variables_page.png | Bin 233764 -> 0 bytes ...ravel_applications_with_gitlab_ci_and_envoy.png | Bin 177704 -> 0 bytes .../index.md | 680 --------------------- 31 files changed, 681 insertions(+), 681 deletions(-) create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_with_image.jpg create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/environment_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/environments_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/laravel_welcome_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/pipeline_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/production_server_app_directory.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/production_server_current_directory.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/secret_variables_page.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/index.md delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png delete mode 100644 doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 5604f52bd94..798d4cbf4ff 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,7 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md) | Tutorial | 2017-08-31 | +| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md) | Tutorial | 2017-08-31 | | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png new file mode 100644 index 00000000000..a56c07a0da7 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png new file mode 100644 index 00000000000..b1406fed6b8 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_with_image.jpg b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_with_image.jpg new file mode 100644 index 00000000000..d1f0cbc08ab Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/container_registry_page_with_image.jpg differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png new file mode 100644 index 00000000000..9aae11b8679 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/environment_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/environment_page.png new file mode 100644 index 00000000000..a06b6d417cd Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/environment_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/environments_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/environments_page.png new file mode 100644 index 00000000000..d357ecda7d2 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/environments_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_welcome_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_welcome_page.png new file mode 100644 index 00000000000..3bb21fd12b4 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_welcome_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/pipeline_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/pipeline_page.png new file mode 100644 index 00000000000..baf8dec499c Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/pipeline_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page.png new file mode 100644 index 00000000000..d96c43bcf16 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png b/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png new file mode 100644 index 00000000000..997db10189f Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_app_directory.png b/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_app_directory.png new file mode 100644 index 00000000000..6dbc29fc25c Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_app_directory.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_current_directory.png b/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_current_directory.png new file mode 100644 index 00000000000..8a6dcccfa38 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/production_server_current_directory.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/secret_variables_page.png b/doc/articles/laravel_with_gitlab_and_envoy/img/secret_variables_page.png new file mode 100644 index 00000000000..658c0b5bcac Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/secret_variables_page.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png b/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png new file mode 100644 index 00000000000..bc188f83fb1 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/index.md b/doc/articles/laravel_with_gitlab_and_envoy/index.md new file mode 100644 index 00000000000..18e42d9f52a --- /dev/null +++ b/doc/articles/laravel_with_gitlab_and_envoy/index.md @@ -0,0 +1,680 @@ +# Test and deploy Laravel applications with GitLab CI/CD and Envoy + +> **Type:** tutorial || +> **Level:** intermediary || +> **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || +> **Publication date:** 2017-08-31 + +## Introduction + +GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. + +In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../../ci/README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). + +We assume you have a basic experience with Laravel, Linux servers, +and you know how to use GitLab. + +Laravel is a high quality web framework written in PHP. +It has a great community with a [fantastic documentation](https://laravel.com/docs). +Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others. + +We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner based on PHP. +It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan). + +## Initialize our Laravel app on GitLab + +We assume [you have installed a new laravel project](https://laravel.com/docs/installation#installation), so let's start with a unit test, and initialize Git for the project. + +### Unit Test + +Every new installation of Laravel (currently 5.4) comes with two type of tests, 'Feature' and 'Unit', placed in the tests directory. +Here's a unit test from `test/Unit/ExampleTest.php`: + +```php +assertTrue(true); + } +} +``` + +This test is as simple as asserting that the given value is true. + +Laravel uses `PHPUnit` for tests by default. +If we run `vendor/bin/phpunit` we should see the green output: + +```bash +vendor/bin/phpunit +OK (1 test, 1 assertions) +``` + +This test will be used later for continuously testing our app with GitLab CI/CD. + +### Push to GitLab + +Since we have our app up and running locally, it's time to push the codebase to our remote repository. +Let's create [a new project](../../gitlab-basics/create-project.md) in GitLab named `laravel-sample`. +After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and push the first commit. + + +```bash +cd laravel-sample +git init +git remote add origin git@gitlab.example.com:/laravel-sample.git +git add . +git commit -m 'Initial Commit' +git push -u origin master +``` + +## Configure the production server + +Before we begin setting up Envoy and GitLab CI/CD, let's quickly make sure the production server is ready for deployment. +We have installed LEMP stack which stands for Linux, Nginx, MySQL and PHP on our Ubuntu 16.04. + +### Create a new user + +Let's now create a new user that will be used to deploy our website and give it +the needed permissions using [Linux ACL](https://serversforhackers.com/video/linux-acls): + +```bash +# Create user deployer +sudo adduser deployer +# Give the read-write-execute permissions to deployer user for directory /var/www +sudo setfacl -R -m u:deployer:rwx /var/www +``` + +If you don't have ACL installed on your Ubuntu server, use this command to install it: + +```bash +sudo apt install acl +``` + +### Add SSH key + +Let's suppose we want to deploy our app to the production server from a private repository on GitLab. First, we need to [generate a new SSH key pair **with no passphrase**](../../ssh/README.md) for the deployer user. + +After that, we need to copy the private key, which will be used to connect to our server as the deployer user with SSH, to be able to automate our deployment process: + +```bash +# As the deployer user on server +# +# Copy the content of public key to authorized_keys +cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys +# Copy the private key text block +cat ~/.ssh/id_rsa +``` + +Now, let's add it to your GitLab project as a [secret variable](../../ci/variables/README.md#secret-variables). +Secret variables are user-defined variables and are stored out of `.gitlab-ci.yml`, for security purposes. +They can be added per project by navigating to the project's **Settings** > **CI/CD**. + +![secret variables page](img/secret_variables_page.png) + +To the field **KEY**, add the name `SSH_PRIVATE_KEY`, and to the **VALUE** field, paste the private key you've copied earlier. +We'll use this variable in the `.gitlab-ci.yml` later, to easily connect to our remote server as the deployer user without entering its password. + +We also need to add the public key to **Project** > **Settings** > **Repository** as [Deploy Keys](../../ssh/README.md/#deploy-keys), which gives us the ability to access our repository from the server through [SSH protocol](../../gitlab-basics/command-line-commands.md/#start-working-on-your-project). + + +```bash +# As the deployer user on the server +# +# Copy the public key +cat ~/.ssh/id_rsa.pub +``` + +![deploy keys page](img/deploy_keys_page.png) + +To the field **Title**, add any name you want, and paste the public key into the **Key** field. + +Now, let's clone our repository on the server just to make sure the `deployer` user has access to the repository. + +```bash +# As the deployer user on server +# +git clone git@gitlab.example.com:/laravel-sample.git +``` + +>**Note:** +Answer **yes** if asked `Are you sure you want to continue connecting (yes/no)?`. +It adds GitLab.com to the known hosts. + +### Configuring Nginx + +Now, let's make sure our web server configuration points to the `current/public` rather than `public`. + +Open the default Nginx server block configuration file by typing: + +```bash +sudo nano /etc/nginx/sites-available/default +``` + +The configuration should be like this. + +``` +server { + root /var/www/app/current/public; + server_name example.com; + # Rest of the configuration +} +``` + +>**Note:** +You may replace the app's name in `/var/www/app/current/public` with the folder name of your application. + +## Setting up Envoy + +So we have our Laravel app ready for production. +The next thing is to use Envoy to perform the deploy. + +To use Envoy, we should first install it on our local machine [using the given instructions by Laravel](https://laravel.com/docs/envoy/#introduction). + +### How Envoy works + +The pros of Envoy is that it doesn't require Blade engine, it just uses Blade syntax to define tasks. +To start, we create an `Envoy.blade.php` in the root of our app with a simple task to test Envoy. + + +```php +@servers(['web' => 'remote_username@remote_host']) + +@task('list', [on => 'web']) + ls -l +@endtask +``` + +As you may expect, we have an array within `@servers` directive at the top of the file, which contains a key named `web` with a value of the server's address (e.g. `deployer@192.168.1.1`). +Then within our `@task` directive we define the bash commands that should be run on the server when the task is executed. + +On the local machine use the `run` command to run Envoy tasks. + +```bash +envoy run list +``` + +It should execute the `list` task we defined earlier, which connects to the server and lists directory contents. + +Envoy is not a dependency of Laravel, therefore you can use it for any PHP application. + +### Zero downtime deployment + +Every time we deploy to the production server, Envoy downloads the latest release of our app from GitLab repository and replace it with preview's release. +Envoy does this without any [downtime](https://en.wikipedia.org/wiki/Downtime), +so we don't have to worry during the deployment while someone might be reviewing the site. +Our deployment plan is to clone the latest release from GitLab repository, install the Composer dependencies and finally, activate the new release. + +#### @setup directive + +The first step of our deployment process is to define a set of variables within [@setup](https://laravel.com/docs/envoy/#setup) directive. +You may change the `app` to your application's name: + + +```php +... + +@setup + $repository = 'git@gitlab.example.com:/laravel-sample.git'; + $releases_dir = '/var/www/app/releases'; + $app_dir = '/var/www/app'; + $release = date('YmdHis'); + $new_release_dir = $releases_dir .'/'. $release; +@endsetup + +... +``` + +- `$repository` is the address of our repository +- `$releases_dir` directory is where we deploy the app +- `$app_dir` is the actual location of the app that is live on the server +- `$release` contains a date, so every time that we deploy a new release of our app, we get a new folder with the current date as name +- `$new_release_dir` is the full path of the new release which is used just to make the tasks cleaner + +#### @story directive + +The [@story](https://laravel.com/docs/envoy/#stories) directive allows us define a list of tasks that can be run as a single task. +Here we have three tasks called `clone_repository`, `run_composer`, `update_symlinks`. These variables are usable to making our task's codes more cleaner: + + +```php +... + +@story('deploy') + clone_repository + run_composer + update_symlinks +@endstory + +... +``` + +Let's create these three tasks one by one. + +#### Clone the repository + +The first task will create the `releases` directory (if it doesn't exist), and then clone the `master` branch of the repository (by default) into the new release directory, given by the `$new_release_dir` variable. +The `releases` directory will hold all our deployments: + +```php +... + +@task('clone_repository') + echo 'Cloning repository' + [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} + git clone --depth 1 {{ $repository }} {{ $new_release_dir }} +@endtask + +... +``` + +While our project grows, its Git history will be very very long over time. +Since we are creating a directory per release, it might not be necessary to have the history of the project downloaded for each release. +The `--depth 1` option is a great solution which saves systems time and disk space as well. + +#### Installing dependencies with Composer + +As you may know, this task just navigates to the new release directory and runs Composer to install the application dependencies: + +```php +... + +@task('run_composer') + echo "Starting deployment ({{ $release }})" + cd {{ $new_release_dir }} + composer install --prefer-dist --no-scripts -q -o +@endtask + +... +``` + +#### Activate new release + +Next thing to do after preparing the requirements of our new release, is to remove the storage directory from it and to create two symbolic links to point the application's `storage` directory and `.env` file to the new release. +Then, we need to create another symbolic link to the new release with the name of `current` placed in the app directory. +The `current` symbolic link always points to the latest release of our app: + +```php +... + +@task('update_symlinks') + echo "Linking storage directory" + rm -rf {{ $new_release_dir }}/storage + ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage + + echo 'Linking .env file' + ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env + + echo 'Linking current release' + ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current +@endtask +``` + +As you see, we use `-nfs` as an option for `ln` command, which says that the `storage`, `.env` and `current` no longer points to the preview's release and will point them to the new release by force (`f` from `-nfs` means force), which is the case when we are doing multiple deployments. + +### Full script + +The script is ready, but make sure to change the `deployer@192.168.1.1` to your server and also change `/var/www/app` with the directory you want to deploy your app. + +At the end, our `Envoy.blade.php` file will look like this: + +```php +@servers(['web' => 'deployer@192.168.1.1']) + +@setup + $repository = 'git@gitlab.example.com:/laravel-sample.git'; + $releases_dir = '/var/www/app/releases'; + $app_dir = '/var/www/app'; + $release = date('YmdHis'); + $new_release_dir = $releases_dir .'/'. $release; +@endsetup + +@story('deploy') + clone_repository + run_composer + update_symlinks +@endstory + +@task('clone_repository') + echo 'Cloning repository' + [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} + git clone --depth 1 {{ $repository }} {{ $new_release_dir }} +@endtask + +@task('run_composer') + echo "Starting deployment ({{ $release }})" + cd {{ $new_release_dir }} + composer install --prefer-dist --no-scripts -q -o +@endtask + +@task('update_symlinks') + echo "Linking storage directory" + rm -rf {{ $new_release_dir }}/storage + ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage + + echo 'Linking .env file' + ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env + + echo 'Linking current release' + ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current +@endtask +``` + +One more thing we should do before any deployment is to manually copy our application `storage` folder to the `/var/www/app` directory on the server for the first time. +You might want to create another Envoy task to do that for you. +We also create the `.env` file in the same path to setup our production environment variables for Laravel. +These are persistent data and will be shared to every new release. + +Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ci/environments.md), which will be described [later](#setting-up-gitlab-ci-cd) in this tutorial. + +Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. +To keep things simple, we commit directly to `master`, without using [feature-branches](../../workflow/gitlab_flow.md/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. +In a real world project, teams may use [Issue Tracker](../../user/project/issues/index.md) and [Merge Requests](../../user/project/merge_requests/index.md) to move their code across branches: + +```bash +git add Envoy.blade.php +git commit -m 'Add Envoy' +git push origin master +``` + +## Continuous Integration with GitLab + +We have our app ready on GitLab, and we also can deploy it manually. +But let's take a step forward to do it automatically with [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) method. +We need to check every commit with a set of automated tests to become aware of issues at the earliest, and then, we can deploy to the target environment if we are happy with the result of the tests. + +[GitLab CI/CD](../../ci/README.md) allows us to use [Docker](https://docker.com/) engine to handle the process of testing and deploying our app. +In the case you're not familiar with Docker, refer to [How to Automate Docker Deployments](http://paislee.io/how-to-automate-docker-deployments/). + +To be able to build, test, and deploy our app with GitLab CI/CD, we need to prepare our work environment. +To do that, we'll use a Docker image which has the minimum requirements that a Laravel app needs to run. +[There are other ways](../../ci/examples/php.md/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. + +With Docker images our builds run incredibly faster! + +### Create a Container Image + +Let's create a [Dockerfile](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Dockerfile) in the root directory of our app with the following content: + +```bash +# Set the base image for subsequent instructions +FROM php:7.1 + +# Update packages +RUN apt-get update + +# Install PHP and composer dependencies +RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev + +# Clear out the local repository of retrieved package files +RUN apt-get clean + +# Install needed extensions +# Here you can install any other extension that you need during the test and deployment process +RUN docker-php-ext-install mcrypt pdo_mysql zip + +# Install Composer +RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Install Laravel Envoy +RUN composer global require "laravel/envoy=~1.0" +``` + +We added the [official PHP 7.1 Docker image](https://hub.docker.com/r/_/php/), which consist of a minimum installation of Debian Jessie with PHP pre-installed, and works perfectly for our use case. + +We used `docker-php-ext-install` (provided by the official PHP Docker image) to install the PHP extensions we need. + +#### Setting Up GitLab Container Registry + +Now that we have our `Dockerfile` let's build and push it to our [GitLab Container Registry](../../user/project/container_registry.md). + +> The registry is the place to store and tag images for later use. Developers may want to maintain their own registry for private, company images, or for throw-away images used only in testing. Using GitLab Container Registry means you don't need to set up and administer yet another service or use a public registry. + +On your GitLab project repository navigate to the **Registry** tab. + +![container registry page empty image](img/container_registry_page_empty_image.png) + +You may need to [enable Container Registry](../../user/project/container_registry.md#enable-the-container-registry-for-your-project) to your project to see this tab. You'll find it under your project's **Settings > General > Sharing and permissions**. + +![container registry checkbox](img/container_registry_checkbox.png) + +To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password: + +```bash +docker login registry.gitlab.com +``` +Then we can build and push our image to GitLab: + +```bash +docker build -t registry.gitlab.com//laravel-sample . + +docker push registry.gitlab.com//laravel-sample +``` + +>**Note:** +To run the above commands, we first need to have [Docker](https://docs.docker.com/engine/installation/) installed on our machine. + +Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it: + +![container registry page with image](img/container_registry_page_with_image.jpg) + +>**Note:** +You can also [use GitLab CI/CD](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine. + +We'll use this image further down in the `.gitlab-ci.yml` configuration file to handle the process of testing and deploying our app. + +Let's commit the `Dockerfile` file. + +```bash +git add Dockerfile +git commit -m 'Add Dockerfile' +git push origin master +``` + +### Setting up GitLab CI/CD + +In order to build and test our app with GitLab CI/CD, we need a file called `.gitlab-ci.yml` in our repository's root. It is similar to Circle CI and Travis CI, but built-in GitLab. + +Our `.gitlab-ci.yml` file will look like this: + +```yaml +image: registry.gitlab.com//laravel-sample:latest + +services: + - mysql:5.7 + +variables: + MYSQL_DATABASE: homestead + MYSQL_ROOT_PASSWORD: secret + DB_HOST: mysql + DB_USERNAME: root + +stages: + - test + - deploy + +unit_test: + stage: test + script: + - composer install + - cp .env.example .env + - php artisan key:generate + - php artisan migrate + - vendor/bin/phpunit + +deploy_production: + stage: deploy + script: + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_PRIVATE_KEY") + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + + - ~/.composer/vendor/bin/envoy run deploy + environment: + name: production + url: http://192.168.1.1 + when: manual + only: + - master +``` + +That's a lot to take in, isn't it? Let's run through it step by step. + +#### Image and Services + +[GitLab Runners](../../ci/runners/README.md) run the script defined by `.gitlab-ci.yml`. +The `image` keyword tells the Runners which image to use. +The `services` keyword defines additional images [that are linked to the main image](../../ci/docker/using_docker_images.md/#what-is-a-service). +Here we use the container image we created before as our main image and also use MySQL 5.7 as a service. + +```yaml +image: registry.gitlab.com//laravel-sample:latest + +services: + - mysql:5.7 + +... +``` + +>**Note:** +If you wish to test your app with different PHP versions and [database management systems](../../ci/services/README.md), you can define different `image` and `services` keywords for each test job. + +#### Variables + +GitLab CI/CD allows us to use [environment variables](../../ci/yaml/README.md#variables) in our jobs. +We defined MySQL as our database management system, which comes with a superuser root created by default. + +So we should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. +Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). + +Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are Laravel specific variables. +We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../../ci/docker/using_docker_images.md/#how-services-are-linked-to-the-build). + +```yaml +... + +variables: + MYSQL_DATABASE: homestead + MYSQL_ROOT_PASSWORD: secret + DB_HOST: mysql + DB_USERNAME: root + +... +``` + +#### Unit Test as the first job + +We defined the required shell scripts as an array of the [script](../../ci/yaml/README.md#script) variable to be executed when running `unit_test` job. + +These scripts are some Artisan commands to prepare the Laravel, and, at the end of the script, we'll run the tests by `PHPUnit`. + +```yaml +... + +unit_test: + script: + # Install app dependencies + - composer install + # Setup .env + - cp .env.example .env + # Generate an environment key + - php artisan key:generate + # Run migrations + - php artisan migrate + # Run tests + - vendor/bin/phpunit + +... +``` + +#### Deploy to production + +The job `deploy_production` will deploy the app to the production server. +To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ci/ssh_keys/README.md/#ssh-keys-when-using-the-docker-executor). +If the SSH keys have added successfully, we can run Envoy. + +As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well. +The [environment](../../ci/yaml/README.md#environment) keyword tells GitLab that this job deploys to the `production` environment. +The `url` keyword is used to generate a link to our application on the GitLab Environments page. +The `only` keyword tells GitLab CI that the job should be executed only when the pipeline is building the `master` branch. +Lastly, `when: manual` is used to turn the job from running automatically to a manual action. + +```yaml +... + +deploy_production: + script: + # Add the private SSH key to the build environment + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_PRIVATE_KEY") + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + + # Run Envoy + - ~/.composer/vendor/bin/envoy run deploy + + environment: + name: production + url: http://192.168.1.1 + when: manual + only: + - master +``` + +You may also want to add another job for [staging environment](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments), to final test your application before deploying to production. + +### Turn on GitLab CI/CD + +We have prepared everything we need to test and deploy our app with GitLab CI/CD. +To do that, commit and push `.gitlab-ci.yml` to the `master` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**. + +![pipelines page](img/pipelines_page.png) + +Here we see our **Test** and **Deploy** stages. +The **Test** stage has the `unit_test` build running. +click on it to see the Runner's output. + +![pipeline page](img/pipeline_page.png) + +After our code passed through the pipeline successfully, we can deploy to our production server by clicking the **play** button on the right side. + +![pipelines page deploy button](img/pipelines_page_deploy_button.png) + +Once the deploy pipeline passed successfully, navigate to **Pipelines > Environments**. + +![environments page](img/environments_page.png) + +If something doesn't work as expected, you can roll back to the latest working version of your app. + +![environment page](img/environment_page.png) + +By clicking on the external link icon specified on the right side, GitLab opens the production website. +Our deployment successfully was done and we can see the application is live. + +![laravel welcome page](img/laravel_welcome_page.png) + +In the case that you're interested to know how is the application directory structure on the production server after deployment, here are three directories named `current`, `releases` and `storage`. +As you know, the `current` directory is a symbolic link that points to the latest release. +The `.env` file consists of our Laravel environment variables. + +![production server app directory](img/production_server_app_directory.png) + +If you navigate to the `current` directory, you should see the application's content. +As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `storage` is pointing to the `/var/www/app/storage/` directory. + +![production server current directory](img/production_server_current_directory.png) + +## Conclusion + +We configured GitLab CI to perform automated tests and used the method of [Continuous Delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. + +Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png deleted file mode 100644 index a56c07a0da7..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_checkbox.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png deleted file mode 100644 index b1406fed6b8..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_empty_image.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg deleted file mode 100644 index d1f0cbc08ab..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/container_registry_page_with_image.jpg and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png deleted file mode 100644 index 9aae11b8679..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/deploy_keys_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png deleted file mode 100644 index a06b6d417cd..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environment_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png deleted file mode 100644 index d357ecda7d2..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/environments_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png deleted file mode 100644 index 3bb21fd12b4..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/laravel_welcome_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png deleted file mode 100644 index baf8dec499c..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipeline_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png deleted file mode 100644 index d96c43bcf16..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png deleted file mode 100644 index 997db10189f..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/pipelines_page_deploy_button.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png deleted file mode 100644 index 6dbc29fc25c..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_app_directory.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png deleted file mode 100644 index 8a6dcccfa38..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/production_server_current_directory.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png deleted file mode 100644 index 658c0b5bcac..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/secret_variables_page.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png deleted file mode 100644 index bc188f83fb1..00000000000 Binary files a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png and /dev/null differ diff --git a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md b/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md deleted file mode 100644 index 18e42d9f52a..00000000000 --- a/doc/articles/test_and_deploy_laravel_apps_with_gitlab_ci_and_envoy/index.md +++ /dev/null @@ -1,680 +0,0 @@ -# Test and deploy Laravel applications with GitLab CI/CD and Envoy - -> **Type:** tutorial || -> **Level:** intermediary || -> **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || -> **Publication date:** 2017-08-31 - -## Introduction - -GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. - -In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../../ci/README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/). - -We assume you have a basic experience with Laravel, Linux servers, -and you know how to use GitLab. - -Laravel is a high quality web framework written in PHP. -It has a great community with a [fantastic documentation](https://laravel.com/docs). -Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others. - -We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner based on PHP. -It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan). - -## Initialize our Laravel app on GitLab - -We assume [you have installed a new laravel project](https://laravel.com/docs/installation#installation), so let's start with a unit test, and initialize Git for the project. - -### Unit Test - -Every new installation of Laravel (currently 5.4) comes with two type of tests, 'Feature' and 'Unit', placed in the tests directory. -Here's a unit test from `test/Unit/ExampleTest.php`: - -```php -assertTrue(true); - } -} -``` - -This test is as simple as asserting that the given value is true. - -Laravel uses `PHPUnit` for tests by default. -If we run `vendor/bin/phpunit` we should see the green output: - -```bash -vendor/bin/phpunit -OK (1 test, 1 assertions) -``` - -This test will be used later for continuously testing our app with GitLab CI/CD. - -### Push to GitLab - -Since we have our app up and running locally, it's time to push the codebase to our remote repository. -Let's create [a new project](../../gitlab-basics/create-project.md) in GitLab named `laravel-sample`. -After that, follow the command line instructions displayed on the project's homepage to initiate the repository on our machine and push the first commit. - - -```bash -cd laravel-sample -git init -git remote add origin git@gitlab.example.com:/laravel-sample.git -git add . -git commit -m 'Initial Commit' -git push -u origin master -``` - -## Configure the production server - -Before we begin setting up Envoy and GitLab CI/CD, let's quickly make sure the production server is ready for deployment. -We have installed LEMP stack which stands for Linux, Nginx, MySQL and PHP on our Ubuntu 16.04. - -### Create a new user - -Let's now create a new user that will be used to deploy our website and give it -the needed permissions using [Linux ACL](https://serversforhackers.com/video/linux-acls): - -```bash -# Create user deployer -sudo adduser deployer -# Give the read-write-execute permissions to deployer user for directory /var/www -sudo setfacl -R -m u:deployer:rwx /var/www -``` - -If you don't have ACL installed on your Ubuntu server, use this command to install it: - -```bash -sudo apt install acl -``` - -### Add SSH key - -Let's suppose we want to deploy our app to the production server from a private repository on GitLab. First, we need to [generate a new SSH key pair **with no passphrase**](../../ssh/README.md) for the deployer user. - -After that, we need to copy the private key, which will be used to connect to our server as the deployer user with SSH, to be able to automate our deployment process: - -```bash -# As the deployer user on server -# -# Copy the content of public key to authorized_keys -cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys -# Copy the private key text block -cat ~/.ssh/id_rsa -``` - -Now, let's add it to your GitLab project as a [secret variable](../../ci/variables/README.md#secret-variables). -Secret variables are user-defined variables and are stored out of `.gitlab-ci.yml`, for security purposes. -They can be added per project by navigating to the project's **Settings** > **CI/CD**. - -![secret variables page](img/secret_variables_page.png) - -To the field **KEY**, add the name `SSH_PRIVATE_KEY`, and to the **VALUE** field, paste the private key you've copied earlier. -We'll use this variable in the `.gitlab-ci.yml` later, to easily connect to our remote server as the deployer user without entering its password. - -We also need to add the public key to **Project** > **Settings** > **Repository** as [Deploy Keys](../../ssh/README.md/#deploy-keys), which gives us the ability to access our repository from the server through [SSH protocol](../../gitlab-basics/command-line-commands.md/#start-working-on-your-project). - - -```bash -# As the deployer user on the server -# -# Copy the public key -cat ~/.ssh/id_rsa.pub -``` - -![deploy keys page](img/deploy_keys_page.png) - -To the field **Title**, add any name you want, and paste the public key into the **Key** field. - -Now, let's clone our repository on the server just to make sure the `deployer` user has access to the repository. - -```bash -# As the deployer user on server -# -git clone git@gitlab.example.com:/laravel-sample.git -``` - ->**Note:** -Answer **yes** if asked `Are you sure you want to continue connecting (yes/no)?`. -It adds GitLab.com to the known hosts. - -### Configuring Nginx - -Now, let's make sure our web server configuration points to the `current/public` rather than `public`. - -Open the default Nginx server block configuration file by typing: - -```bash -sudo nano /etc/nginx/sites-available/default -``` - -The configuration should be like this. - -``` -server { - root /var/www/app/current/public; - server_name example.com; - # Rest of the configuration -} -``` - ->**Note:** -You may replace the app's name in `/var/www/app/current/public` with the folder name of your application. - -## Setting up Envoy - -So we have our Laravel app ready for production. -The next thing is to use Envoy to perform the deploy. - -To use Envoy, we should first install it on our local machine [using the given instructions by Laravel](https://laravel.com/docs/envoy/#introduction). - -### How Envoy works - -The pros of Envoy is that it doesn't require Blade engine, it just uses Blade syntax to define tasks. -To start, we create an `Envoy.blade.php` in the root of our app with a simple task to test Envoy. - - -```php -@servers(['web' => 'remote_username@remote_host']) - -@task('list', [on => 'web']) - ls -l -@endtask -``` - -As you may expect, we have an array within `@servers` directive at the top of the file, which contains a key named `web` with a value of the server's address (e.g. `deployer@192.168.1.1`). -Then within our `@task` directive we define the bash commands that should be run on the server when the task is executed. - -On the local machine use the `run` command to run Envoy tasks. - -```bash -envoy run list -``` - -It should execute the `list` task we defined earlier, which connects to the server and lists directory contents. - -Envoy is not a dependency of Laravel, therefore you can use it for any PHP application. - -### Zero downtime deployment - -Every time we deploy to the production server, Envoy downloads the latest release of our app from GitLab repository and replace it with preview's release. -Envoy does this without any [downtime](https://en.wikipedia.org/wiki/Downtime), -so we don't have to worry during the deployment while someone might be reviewing the site. -Our deployment plan is to clone the latest release from GitLab repository, install the Composer dependencies and finally, activate the new release. - -#### @setup directive - -The first step of our deployment process is to define a set of variables within [@setup](https://laravel.com/docs/envoy/#setup) directive. -You may change the `app` to your application's name: - - -```php -... - -@setup - $repository = 'git@gitlab.example.com:/laravel-sample.git'; - $releases_dir = '/var/www/app/releases'; - $app_dir = '/var/www/app'; - $release = date('YmdHis'); - $new_release_dir = $releases_dir .'/'. $release; -@endsetup - -... -``` - -- `$repository` is the address of our repository -- `$releases_dir` directory is where we deploy the app -- `$app_dir` is the actual location of the app that is live on the server -- `$release` contains a date, so every time that we deploy a new release of our app, we get a new folder with the current date as name -- `$new_release_dir` is the full path of the new release which is used just to make the tasks cleaner - -#### @story directive - -The [@story](https://laravel.com/docs/envoy/#stories) directive allows us define a list of tasks that can be run as a single task. -Here we have three tasks called `clone_repository`, `run_composer`, `update_symlinks`. These variables are usable to making our task's codes more cleaner: - - -```php -... - -@story('deploy') - clone_repository - run_composer - update_symlinks -@endstory - -... -``` - -Let's create these three tasks one by one. - -#### Clone the repository - -The first task will create the `releases` directory (if it doesn't exist), and then clone the `master` branch of the repository (by default) into the new release directory, given by the `$new_release_dir` variable. -The `releases` directory will hold all our deployments: - -```php -... - -@task('clone_repository') - echo 'Cloning repository' - [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} - git clone --depth 1 {{ $repository }} {{ $new_release_dir }} -@endtask - -... -``` - -While our project grows, its Git history will be very very long over time. -Since we are creating a directory per release, it might not be necessary to have the history of the project downloaded for each release. -The `--depth 1` option is a great solution which saves systems time and disk space as well. - -#### Installing dependencies with Composer - -As you may know, this task just navigates to the new release directory and runs Composer to install the application dependencies: - -```php -... - -@task('run_composer') - echo "Starting deployment ({{ $release }})" - cd {{ $new_release_dir }} - composer install --prefer-dist --no-scripts -q -o -@endtask - -... -``` - -#### Activate new release - -Next thing to do after preparing the requirements of our new release, is to remove the storage directory from it and to create two symbolic links to point the application's `storage` directory and `.env` file to the new release. -Then, we need to create another symbolic link to the new release with the name of `current` placed in the app directory. -The `current` symbolic link always points to the latest release of our app: - -```php -... - -@task('update_symlinks') - echo "Linking storage directory" - rm -rf {{ $new_release_dir }}/storage - ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage - - echo 'Linking .env file' - ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env - - echo 'Linking current release' - ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current -@endtask -``` - -As you see, we use `-nfs` as an option for `ln` command, which says that the `storage`, `.env` and `current` no longer points to the preview's release and will point them to the new release by force (`f` from `-nfs` means force), which is the case when we are doing multiple deployments. - -### Full script - -The script is ready, but make sure to change the `deployer@192.168.1.1` to your server and also change `/var/www/app` with the directory you want to deploy your app. - -At the end, our `Envoy.blade.php` file will look like this: - -```php -@servers(['web' => 'deployer@192.168.1.1']) - -@setup - $repository = 'git@gitlab.example.com:/laravel-sample.git'; - $releases_dir = '/var/www/app/releases'; - $app_dir = '/var/www/app'; - $release = date('YmdHis'); - $new_release_dir = $releases_dir .'/'. $release; -@endsetup - -@story('deploy') - clone_repository - run_composer - update_symlinks -@endstory - -@task('clone_repository') - echo 'Cloning repository' - [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }} - git clone --depth 1 {{ $repository }} {{ $new_release_dir }} -@endtask - -@task('run_composer') - echo "Starting deployment ({{ $release }})" - cd {{ $new_release_dir }} - composer install --prefer-dist --no-scripts -q -o -@endtask - -@task('update_symlinks') - echo "Linking storage directory" - rm -rf {{ $new_release_dir }}/storage - ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage - - echo 'Linking .env file' - ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env - - echo 'Linking current release' - ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current -@endtask -``` - -One more thing we should do before any deployment is to manually copy our application `storage` folder to the `/var/www/app` directory on the server for the first time. -You might want to create another Envoy task to do that for you. -We also create the `.env` file in the same path to setup our production environment variables for Laravel. -These are persistent data and will be shared to every new release. - -Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../ci/environments.md), which will be described [later](#setting-up-gitlab-ci-cd) in this tutorial. - -Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch. -To keep things simple, we commit directly to `master`, without using [feature-branches](../../workflow/gitlab_flow.md/#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial. -In a real world project, teams may use [Issue Tracker](../../user/project/issues/index.md) and [Merge Requests](../../user/project/merge_requests/index.md) to move their code across branches: - -```bash -git add Envoy.blade.php -git commit -m 'Add Envoy' -git push origin master -``` - -## Continuous Integration with GitLab - -We have our app ready on GitLab, and we also can deploy it manually. -But let's take a step forward to do it automatically with [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) method. -We need to check every commit with a set of automated tests to become aware of issues at the earliest, and then, we can deploy to the target environment if we are happy with the result of the tests. - -[GitLab CI/CD](../../ci/README.md) allows us to use [Docker](https://docker.com/) engine to handle the process of testing and deploying our app. -In the case you're not familiar with Docker, refer to [How to Automate Docker Deployments](http://paislee.io/how-to-automate-docker-deployments/). - -To be able to build, test, and deploy our app with GitLab CI/CD, we need to prepare our work environment. -To do that, we'll use a Docker image which has the minimum requirements that a Laravel app needs to run. -[There are other ways](../../ci/examples/php.md/#test-php-projects-using-the-docker-executor) to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use. - -With Docker images our builds run incredibly faster! - -### Create a Container Image - -Let's create a [Dockerfile](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Dockerfile) in the root directory of our app with the following content: - -```bash -# Set the base image for subsequent instructions -FROM php:7.1 - -# Update packages -RUN apt-get update - -# Install PHP and composer dependencies -RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev - -# Clear out the local repository of retrieved package files -RUN apt-get clean - -# Install needed extensions -# Here you can install any other extension that you need during the test and deployment process -RUN docker-php-ext-install mcrypt pdo_mysql zip - -# Install Composer -RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer - -# Install Laravel Envoy -RUN composer global require "laravel/envoy=~1.0" -``` - -We added the [official PHP 7.1 Docker image](https://hub.docker.com/r/_/php/), which consist of a minimum installation of Debian Jessie with PHP pre-installed, and works perfectly for our use case. - -We used `docker-php-ext-install` (provided by the official PHP Docker image) to install the PHP extensions we need. - -#### Setting Up GitLab Container Registry - -Now that we have our `Dockerfile` let's build and push it to our [GitLab Container Registry](../../user/project/container_registry.md). - -> The registry is the place to store and tag images for later use. Developers may want to maintain their own registry for private, company images, or for throw-away images used only in testing. Using GitLab Container Registry means you don't need to set up and administer yet another service or use a public registry. - -On your GitLab project repository navigate to the **Registry** tab. - -![container registry page empty image](img/container_registry_page_empty_image.png) - -You may need to [enable Container Registry](../../user/project/container_registry.md#enable-the-container-registry-for-your-project) to your project to see this tab. You'll find it under your project's **Settings > General > Sharing and permissions**. - -![container registry checkbox](img/container_registry_checkbox.png) - -To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password: - -```bash -docker login registry.gitlab.com -``` -Then we can build and push our image to GitLab: - -```bash -docker build -t registry.gitlab.com//laravel-sample . - -docker push registry.gitlab.com//laravel-sample -``` - ->**Note:** -To run the above commands, we first need to have [Docker](https://docs.docker.com/engine/installation/) installed on our machine. - -Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it: - -![container registry page with image](img/container_registry_page_with_image.jpg) - ->**Note:** -You can also [use GitLab CI/CD](https://about.gitlab.com/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine. - -We'll use this image further down in the `.gitlab-ci.yml` configuration file to handle the process of testing and deploying our app. - -Let's commit the `Dockerfile` file. - -```bash -git add Dockerfile -git commit -m 'Add Dockerfile' -git push origin master -``` - -### Setting up GitLab CI/CD - -In order to build and test our app with GitLab CI/CD, we need a file called `.gitlab-ci.yml` in our repository's root. It is similar to Circle CI and Travis CI, but built-in GitLab. - -Our `.gitlab-ci.yml` file will look like this: - -```yaml -image: registry.gitlab.com//laravel-sample:latest - -services: - - mysql:5.7 - -variables: - MYSQL_DATABASE: homestead - MYSQL_ROOT_PASSWORD: secret - DB_HOST: mysql - DB_USERNAME: root - -stages: - - test - - deploy - -unit_test: - stage: test - script: - - composer install - - cp .env.example .env - - php artisan key:generate - - php artisan migrate - - vendor/bin/phpunit - -deploy_production: - stage: deploy - script: - - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - ssh-add <(echo "$SSH_PRIVATE_KEY") - - mkdir -p ~/.ssh - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' - - - ~/.composer/vendor/bin/envoy run deploy - environment: - name: production - url: http://192.168.1.1 - when: manual - only: - - master -``` - -That's a lot to take in, isn't it? Let's run through it step by step. - -#### Image and Services - -[GitLab Runners](../../ci/runners/README.md) run the script defined by `.gitlab-ci.yml`. -The `image` keyword tells the Runners which image to use. -The `services` keyword defines additional images [that are linked to the main image](../../ci/docker/using_docker_images.md/#what-is-a-service). -Here we use the container image we created before as our main image and also use MySQL 5.7 as a service. - -```yaml -image: registry.gitlab.com//laravel-sample:latest - -services: - - mysql:5.7 - -... -``` - ->**Note:** -If you wish to test your app with different PHP versions and [database management systems](../../ci/services/README.md), you can define different `image` and `services` keywords for each test job. - -#### Variables - -GitLab CI/CD allows us to use [environment variables](../../ci/yaml/README.md#variables) in our jobs. -We defined MySQL as our database management system, which comes with a superuser root created by default. - -So we should adjust the configuration of MySQL instance by defining `MYSQL_DATABASE` variable as our database name and `MYSQL_ROOT_PASSWORD` variable as the password of `root`. -Find out more about MySQL variables at the [official MySQL Docker Image](https://hub.docker.com/r/_/mysql/). - -Also set the variables `DB_HOST` to `mysql` and `DB_USERNAME` to `root`, which are Laravel specific variables. -We define `DB_HOST` as `mysql` instead of `127.0.0.1`, as we use MySQL Docker image as a service which [is linked to the main Docker image](../../ci/docker/using_docker_images.md/#how-services-are-linked-to-the-build). - -```yaml -... - -variables: - MYSQL_DATABASE: homestead - MYSQL_ROOT_PASSWORD: secret - DB_HOST: mysql - DB_USERNAME: root - -... -``` - -#### Unit Test as the first job - -We defined the required shell scripts as an array of the [script](../../ci/yaml/README.md#script) variable to be executed when running `unit_test` job. - -These scripts are some Artisan commands to prepare the Laravel, and, at the end of the script, we'll run the tests by `PHPUnit`. - -```yaml -... - -unit_test: - script: - # Install app dependencies - - composer install - # Setup .env - - cp .env.example .env - # Generate an environment key - - php artisan key:generate - # Run migrations - - php artisan migrate - # Run tests - - vendor/bin/phpunit - -... -``` - -#### Deploy to production - -The job `deploy_production` will deploy the app to the production server. -To deploy our app with Envoy, we had to set up the `$SSH_PRIVATE_KEY` variable as an [SSH private key](../../ci/ssh_keys/README.md/#ssh-keys-when-using-the-docker-executor). -If the SSH keys have added successfully, we can run Envoy. - -As mentioned before, GitLab supports [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#continuous-delivery) methods as well. -The [environment](../../ci/yaml/README.md#environment) keyword tells GitLab that this job deploys to the `production` environment. -The `url` keyword is used to generate a link to our application on the GitLab Environments page. -The `only` keyword tells GitLab CI that the job should be executed only when the pipeline is building the `master` branch. -Lastly, `when: manual` is used to turn the job from running automatically to a manual action. - -```yaml -... - -deploy_production: - script: - # Add the private SSH key to the build environment - - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - - eval $(ssh-agent -s) - - ssh-add <(echo "$SSH_PRIVATE_KEY") - - mkdir -p ~/.ssh - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' - - # Run Envoy - - ~/.composer/vendor/bin/envoy run deploy - - environment: - name: production - url: http://192.168.1.1 - when: manual - only: - - master -``` - -You may also want to add another job for [staging environment](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments), to final test your application before deploying to production. - -### Turn on GitLab CI/CD - -We have prepared everything we need to test and deploy our app with GitLab CI/CD. -To do that, commit and push `.gitlab-ci.yml` to the `master` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**. - -![pipelines page](img/pipelines_page.png) - -Here we see our **Test** and **Deploy** stages. -The **Test** stage has the `unit_test` build running. -click on it to see the Runner's output. - -![pipeline page](img/pipeline_page.png) - -After our code passed through the pipeline successfully, we can deploy to our production server by clicking the **play** button on the right side. - -![pipelines page deploy button](img/pipelines_page_deploy_button.png) - -Once the deploy pipeline passed successfully, navigate to **Pipelines > Environments**. - -![environments page](img/environments_page.png) - -If something doesn't work as expected, you can roll back to the latest working version of your app. - -![environment page](img/environment_page.png) - -By clicking on the external link icon specified on the right side, GitLab opens the production website. -Our deployment successfully was done and we can see the application is live. - -![laravel welcome page](img/laravel_welcome_page.png) - -In the case that you're interested to know how is the application directory structure on the production server after deployment, here are three directories named `current`, `releases` and `storage`. -As you know, the `current` directory is a symbolic link that points to the latest release. -The `.env` file consists of our Laravel environment variables. - -![production server app directory](img/production_server_app_directory.png) - -If you navigate to the `current` directory, you should see the application's content. -As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `storage` is pointing to the `/var/www/app/storage/` directory. - -![production server current directory](img/production_server_current_directory.png) - -## Conclusion - -We configured GitLab CI to perform automated tests and used the method of [Continuous Delivery](https://continuousdelivery.com/) to deploy to production a Laravel application with Envoy, directly from the codebase. - -Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics. -- cgit v1.2.1 From 09f2c8ca30ca7e33119572da1773240129ff3aed Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 14:31:09 -0300 Subject: correct date format --- doc/articles/numerous_undo_possibilities_in_git/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/articles') diff --git a/doc/articles/numerous_undo_possibilities_in_git/index.md b/doc/articles/numerous_undo_possibilities_in_git/index.md index 9f1239b8f88..895bbccec08 100644 --- a/doc/articles/numerous_undo_possibilities_in_git/index.md +++ b/doc/articles/numerous_undo_possibilities_in_git/index.md @@ -3,7 +3,7 @@ > **Article [Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Crt Mori](https://gitlab.com/Letme) || -> **Publication date:** 2017/08/17 +> **Publication date:** 2017-08-17 ## Introduction -- cgit v1.2.1 From 4074cf52ec755456771c84bedb0a548505847c8e Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 14:34:06 -0300 Subject: adjust date --- doc/articles/index.md | 2 +- doc/articles/laravel_with_gitlab_and_envoy/index.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 798d4cbf4ff..450bd3ce9e6 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,7 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md) | Tutorial | 2017-08-31 | +| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md) | Tutorial | 2017-09-01 | | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | diff --git a/doc/articles/laravel_with_gitlab_and_envoy/index.md b/doc/articles/laravel_with_gitlab_and_envoy/index.md index 18e42d9f52a..04899b82e3d 100644 --- a/doc/articles/laravel_with_gitlab_and_envoy/index.md +++ b/doc/articles/laravel_with_gitlab_and_envoy/index.md @@ -1,9 +1,9 @@ # Test and deploy Laravel applications with GitLab CI/CD and Envoy -> **Type:** tutorial || +> **[Article Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || -> **Publication date:** 2017-08-31 +> **Publication date:** 2017-09-01 ## Introduction -- cgit v1.2.1 From 53601b5a0085aa00711c5c7a0f386250cbf914c7 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 15:07:36 -0300 Subject: rename image social sharing image --- .../img/laravel_with_gitlab_and_envoy.png | Bin 0 -> 177704 bytes ...y_laravel_applications_with_gitlab_ci_and_envoy.png | Bin 177704 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/laravel_with_gitlab_and_envoy.png delete mode 100644 doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png (limited to 'doc/articles') diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_with_gitlab_and_envoy.png b/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_with_gitlab_and_envoy.png new file mode 100644 index 00000000000..bc188f83fb1 Binary files /dev/null and b/doc/articles/laravel_with_gitlab_and_envoy/img/laravel_with_gitlab_and_envoy.png differ diff --git a/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png b/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png deleted file mode 100644 index bc188f83fb1..00000000000 Binary files a/doc/articles/laravel_with_gitlab_and_envoy/img/test_and_deploy_laravel_applications_with_gitlab_ci_and_envoy.png and /dev/null differ -- cgit v1.2.1 From b3fa033d883d291e3b5ad25ba8e564d856e329b1 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 31 Aug 2017 16:12:48 -0300 Subject: fix date --- doc/articles/index.md | 2 +- doc/articles/laravel_with_gitlab_and_envoy/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'doc/articles') diff --git a/doc/articles/index.md b/doc/articles/index.md index 450bd3ce9e6..798d4cbf4ff 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -26,7 +26,7 @@ Build, test, and deploy the software you develop with [GitLab CI/CD](../ci/READM | Article title | Category | Publishing date | | :------------ | :------: | --------------: | -| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md) | Tutorial | 2017-09-01 | +| [How to test and deploy Laravel/PHP applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md) | Tutorial | 2017-08-31 | | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md) | Tutorial | 2017-08-15 | | [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/) | Concepts | 2017-07-13 | | [Dockerizing GitLab Review Apps](https://about.gitlab.com/2017/07/11/dockerizing-review-apps/) | Concepts | 2017-07-11 | diff --git a/doc/articles/laravel_with_gitlab_and_envoy/index.md b/doc/articles/laravel_with_gitlab_and_envoy/index.md index 04899b82e3d..e0d8fb8d081 100644 --- a/doc/articles/laravel_with_gitlab_and_envoy/index.md +++ b/doc/articles/laravel_with_gitlab_and_envoy/index.md @@ -3,7 +3,7 @@ > **[Article Type](../../development/writing_documentation.md#types-of-technical-articles):** tutorial || > **Level:** intermediary || > **Author:** [Mehran Rasulian](https://gitlab.com/mehranrasulian) || -> **Publication date:** 2017-09-01 +> **Publication date:** 2017-08-31 ## Introduction -- cgit v1.2.1