diff options
author | Nick Thomas <nick@gitlab.com> | 2016-12-08 16:21:16 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2016-12-15 14:17:58 +0000 |
commit | 80513a129592583ed100e7a90fc9ea144eb62ea9 (patch) | |
tree | 54d78eed2625e5c70b64630e6ab2d39c3adc11bd | |
parent | 58486918fc12bbcc5139b6ca32461ad5e037497b (diff) | |
download | gitlab-ce-80513a129592583ed100e7a90fc9ea144eb62ea9.tar.gz |
Add $CI_ENVIRONMENT_NAME and $CI_ENVIRONMENT_SLUG
-rw-r--r-- | app/models/ci/build.rb | 20 | ||||
-rw-r--r-- | app/models/environment.rb | 7 | ||||
-rw-r--r-- | doc/ci/environments.md | 34 | ||||
-rw-r--r-- | doc/ci/variables/README.md | 2 | ||||
-rw-r--r-- | doc/ci/yaml/README.md | 22 | ||||
-rw-r--r-- | spec/models/build_spec.rb | 36 |
6 files changed, 96 insertions, 25 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 45a416a4c41..fdbf28a1d68 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -9,6 +9,14 @@ module Ci has_many :deployments, as: :deployable + # The "environment" field for builds is a String, and is the unexpanded name + def persisted_environment + @persisted_environment ||= Environment.find_by( + name: expanded_environment_name, + project_id: gl_project_id + ) + end + serialize :options serialize :yaml_variables @@ -143,7 +151,7 @@ module Ci end def expanded_environment_name - ExpandVariables.expand(environment, variables) if environment + ExpandVariables.expand(environment, simple_variables) if environment end def has_environment? @@ -206,7 +214,8 @@ module Ci slugified.gsub(/[^a-z0-9]/, '-')[0..62] end - def variables + # Variables whose value does not depend on other variables + def simple_variables variables = predefined_variables variables += project.predefined_variables variables += pipeline.predefined_variables @@ -219,6 +228,13 @@ module Ci variables end + # All variables, including those dependent on other variables + def variables + variables = simple_variables + variables += persisted_environment.predefined_variables if persisted_environment.present? + variables + end + def merge_request merge_requests = MergeRequest.includes(:merge_request_diff) .where(source_branch: ref, source_project_id: pipeline.gl_project_id) diff --git a/app/models/environment.rb b/app/models/environment.rb index 0abbf674b9d..8ef1c841ea3 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -50,6 +50,13 @@ class Environment < ActiveRecord::Base state :stopped end + def predefined_variables + [ + { key: 'CI_ENVIRONMENT_NAME', value: name, public: true }, + { key: 'CI_ENVIRONMENT_SLUG', value: slug, public: true }, + ] + end + def recently_updated_on_branch?(ref) ref.to_s == last_deployment.try(:ref) end diff --git a/doc/ci/environments.md b/doc/ci/environments.md index 705bca6cc1f..bad0233a9ce 100644 --- a/doc/ci/environments.md +++ b/doc/ci/environments.md @@ -86,6 +86,13 @@ will later see, is exposed in various places within GitLab. Each time a job that has an environment specified and succeeds, a deployment is recorded, remembering the Git SHA and environment name. +>**Note:** +Starting with GitLab 8.15, the environment name is exposed to the Runner in +two forms: `$CI_ENVIRONMENT_NAME`, and `$CI_ENVIRONMENT_SLUG`. The first is +the name given in `.gitlab-ci.yml` (with any variables expanded), while the +second is a "cleaned-up" version of the name, suitable for use in URLs, DNS, +etc. + To sum up, with the above `.gitlab-ci.yml` we have achieved that: - All branches will run the `test` and `build` jobs. @@ -157,7 +164,7 @@ that can be found in the deployments page job with the commit associated with it. >**Note:** -Bare in mind that your mileage will vary and it's entirely up to how you define +Bear in mind that your mileage will vary and it's entirely up to how you define the deployment process in the job's `script` whether the rollback succeeds or not. GitLab CI is just following orders. @@ -248,7 +255,7 @@ deploy_review: - echo "Deploy a review app" environment: name: review/$CI_BUILD_REF_NAME - url: https://$CI_BUILD_REF_SLUG.example.com + url: https://$CI_BUILD_REF_SLUG.review.example.com only: - branches except: @@ -266,9 +273,18 @@ ones. So, the first part is `review`, followed by a `/` and then `$CI_BUILD_REF_NAME` which takes the value of the branch name. Since `$CI_BUILD_REF_NAME` itself may also contain `/`, or other characters that would be invalid in a domain name or -URL, we use `$CI_BUILD_REF_SLUG` in the `environment:url` so that the environment -can get a specific and distinct URL for each branch. Again, the way you set up -the webserver to serve these requests is based on your setup. +URL, we use `$CI_ENVIRONMENT_SLUG` in the `environment:url` so that the +environment can get a specific and distinct URL for each branch. In this case, +given a `$CI_BUILD_REF_NAME` of `100-Do-The-Thing`, the URL will be something +like `https://review-100-do-the-4f99a2.example.com`. Again, the way you set up +the web server to serve these requests is based on your setup. + +You could also use `$CI_BUILD_REF_SLUG` in `environment:url`, e.g.: +`https://$CI_BUILD_REF_SLUG.review.example.com`. We use `$CI_ENVIRONMENT_SLUG` +here because it is guaranteed to be unique, but if you're using a workflow like +[GitLab Flow][gitlab-flow], collisions are very unlikely, and you may prefer +environment names to be more closely based on the branch name - the example +above would give you an URL like `https://100-do-the-thing.review.example.com` Last but not least, we tell the job to run [`only`][only] on branches [`except`][only] master. @@ -300,7 +316,7 @@ deploy_review: - echo "Deploy a review app" environment: name: review/$CI_BUILD_REF_NAME - url: https://$CI_BUILD_REF_SLUG.example.com + url: https://$CI_ENVIRONMENT_SLUG.example.com only: - branches except: @@ -419,7 +435,7 @@ deploy_review: - echo "Deploy a review app" environment: name: review/$CI_BUILD_REF_NAME - url: https://$CI_BUILD_REF_SLUG.example.com + url: https://$CI_ENVIRONMENT_SLUG.example.com on_stop: stop_review only: - branches @@ -493,10 +509,6 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/* ## Limitations -1. `$CI_BUILD_REF_SLUG` is not *guaranteed* to be unique, so there is a small - chance of collisions between similarly-named branches (`fix-foo` would - conflict with `fix/foo`, for instance). Following a well-defined workflow - such as [GitLab Flow][gitlab-flow] can keep this from being a problem. 1. You are limited to use only the [CI predefined variables][variables] in the `environment: name`. If you try to re-use variables defined inside `script` as part of the environment name, it will not work. diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index e0ff9756868..eb540a50606 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -52,6 +52,8 @@ version of Runner required. | **CI_PROJECT_PATH** | 8.10 | 0.5 | The namespace with project name | | **CI_PROJECT_URL** | 8.10 | 0.5 | The HTTP address to access project | | **CI_PROJECT_DIR** | all | all | The full path where the repository is cloned and where the build is run | +| **CI_ENVIRONMENT_NAME** | 8.15 | all | The name of the environment for this build | +| **CI_ENVIRONMENT_SLUG** | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. | | **CI_REGISTRY** | 8.10 | 0.5 | If the Container Registry is enabled it returns the address of GitLab's Container Registry | | **CI_REGISTRY_IMAGE** | 8.10 | 0.5 | If the Container Registry is enabled for the project it returns the address of the registry tied to the specific project | | **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used | diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 5e8d888e555..a62193700fc 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -690,7 +690,7 @@ The `stop_review_app` job is **required** to have the following keywords defined #### dynamic environments > [Introduced][ce-6323] in GitLab 8.12 and GitLab Runner 1.6. - `$CI_BUILD_REF_SLUG` was [introduced][ce-8072] in GitLab 8.15. + `$CI_ENVIRONMENT_SLUG` was [introduced][ce-7983] in GitLab 8.15 `environment` can also represent a configuration hash with `name` and `url`. These parameters can use any of the defined [CI variables](#variables) @@ -703,15 +703,17 @@ deploy as review app: stage: deploy script: make deploy environment: - name: review-apps/$CI_BUILD_REF_NAME - url: https://$CI_BUILD_REF_SLUG.review.example.com/ + name: review/$CI_BUILD_REF_NAME + url: https://$CI_ENVIRONMENT_SLUG.example.com/ ``` The `deploy as review app` job will be marked as deployment to dynamically -create the `review-apps/$CI_BUILD_REF_NAME` environment, which `$CI_BUILD_REF_NAME` -is an [environment variable][variables] set by the Runner. If for example the -`deploy as review app` job was run in a branch named `pow`, this environment -should be accessible under `https://pow.review.example.com/`. +create the `review/$CI_BUILD_REF_NAME` environment, where `$CI_BUILD_REF_NAME` +is an [environment variable][variables] set by the Runner. The +`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable +for inclusion in URLs. In this case, if the `deploy as review app` job was run +in a branch named `pow`, this environment would be accessible with an URL like +`https://review-pow-aaaaaa.example.com/`. This of course implies that the underlying server which hosts the application is properly configured. @@ -720,10 +722,6 @@ The common use case is to create dynamic environments for branches and use them as Review Apps. You can see a simple example using Review Apps at https://gitlab.com/gitlab-examples/review-apps-nginx/. -`$CI_BUILD_REF_SLUG` is another environment variable set by the runner, based on -`$CI_BUILD_REF_NAME` but lower-cased, and with some characters replaced with -`-`, making it suitable for use in URLs and domain names. - ### artifacts >**Notes:** @@ -1243,5 +1241,5 @@ CI with various languages. [ce-6323]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6323 [environment]: ../environments.md [ce-6669]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6669 -[ce-8072]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/xxxx [variables]: ../variables/README.md +[ce-7983]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7983 diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index ea60c17a58a..d5f2ffcff59 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -87,6 +87,26 @@ describe Ci::Build, models: true do end end + describe '#persisted_environment' do + before do + @environment = create(:environment, project: project, name: "foo-#{project.default_branch}") + end + + subject { build.persisted_environment } + + context 'referenced literally' do + let(:build) { create(:ci_build, pipeline: pipeline, environment: "foo-#{project.default_branch}") } + + it { is_expected.to eq(@environment) } + end + + context 'referenced with a variable' do + let(:build) { create(:ci_build, pipeline: pipeline, environment: "foo-$CI_BUILD_REF_NAME") } + + it { is_expected.to eq(@environment) } + end + end + describe '#trace' do it { expect(build.trace).to be_nil } @@ -328,6 +348,22 @@ describe Ci::Build, models: true do it { user_variables.each { |v| is_expected.to include(v) } } end + context 'when build has an environment' do + before do + build.update(environment: 'production') + create(:environment, project: build.project, name: 'production', slug: 'prod-slug') + end + + let(:environment_variables) do + [ + { key: 'CI_ENVIRONMENT_NAME', value: 'production', public: true }, + { key: 'CI_ENVIRONMENT_SLUG', value: 'prod-slug', public: true } + ] + end + + it { environment_variables.each { |v| is_expected.to include(v) } } + end + context 'when build started manually' do before do build.update_attributes(when: :manual) |