summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2016-12-08 16:21:16 +0000
committerNick Thomas <nick@gitlab.com>2016-12-15 14:17:58 +0000
commit80513a129592583ed100e7a90fc9ea144eb62ea9 (patch)
tree54d78eed2625e5c70b64630e6ab2d39c3adc11bd
parent58486918fc12bbcc5139b6ca32461ad5e037497b (diff)
downloadgitlab-ce-80513a129592583ed100e7a90fc9ea144eb62ea9.tar.gz
Add $CI_ENVIRONMENT_NAME and $CI_ENVIRONMENT_SLUG
-rw-r--r--app/models/ci/build.rb20
-rw-r--r--app/models/environment.rb7
-rw-r--r--doc/ci/environments.md34
-rw-r--r--doc/ci/variables/README.md2
-rw-r--r--doc/ci/yaml/README.md22
-rw-r--r--spec/models/build_spec.rb36
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)