Commit 80513a12 authored by Nick Thomas's avatar Nick Thomas

Add $CI_ENVIRONMENT_NAME and $CI_ENVIRONMENT_SLUG

parent 58486918
...@@ -9,6 +9,14 @@ module Ci ...@@ -9,6 +9,14 @@ module Ci
has_many :deployments, as: :deployable 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 :options
serialize :yaml_variables serialize :yaml_variables
...@@ -143,7 +151,7 @@ module Ci ...@@ -143,7 +151,7 @@ module Ci
end end
def expanded_environment_name def expanded_environment_name
ExpandVariables.expand(environment, variables) if environment ExpandVariables.expand(environment, simple_variables) if environment
end end
def has_environment? def has_environment?
...@@ -206,7 +214,8 @@ module Ci ...@@ -206,7 +214,8 @@ module Ci
slugified.gsub(/[^a-z0-9]/, '-')[0..62] slugified.gsub(/[^a-z0-9]/, '-')[0..62]
end end
def variables # Variables whose value does not depend on other variables
def simple_variables
variables = predefined_variables variables = predefined_variables
variables += project.predefined_variables variables += project.predefined_variables
variables += pipeline.predefined_variables variables += pipeline.predefined_variables
...@@ -219,6 +228,13 @@ module Ci ...@@ -219,6 +228,13 @@ module Ci
variables variables
end 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 def merge_request
merge_requests = MergeRequest.includes(:merge_request_diff) merge_requests = MergeRequest.includes(:merge_request_diff)
.where(source_branch: ref, source_project_id: pipeline.gl_project_id) .where(source_branch: ref, source_project_id: pipeline.gl_project_id)
......
...@@ -50,6 +50,13 @@ class Environment < ActiveRecord::Base ...@@ -50,6 +50,13 @@ class Environment < ActiveRecord::Base
state :stopped state :stopped
end 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) def recently_updated_on_branch?(ref)
ref.to_s == last_deployment.try(:ref) ref.to_s == last_deployment.try(:ref)
end end
......
...@@ -86,6 +86,13 @@ will later see, is exposed in various places within GitLab. Each time a job that ...@@ -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 has an environment specified and succeeds, a deployment is recorded, remembering
the Git SHA and environment name. 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: To sum up, with the above `.gitlab-ci.yml` we have achieved that:
- All branches will run the `test` and `build` jobs. - All branches will run the `test` and `build` jobs.
...@@ -157,7 +164,7 @@ that can be found in the deployments page ...@@ -157,7 +164,7 @@ that can be found in the deployments page
job with the commit associated with it. job with the commit associated with it.
>**Note:** >**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. the deployment process in the job's `script` whether the rollback succeeds or not.
GitLab CI is just following orders. GitLab CI is just following orders.
...@@ -248,7 +255,7 @@ deploy_review: ...@@ -248,7 +255,7 @@ deploy_review:
- echo "Deploy a review app" - echo "Deploy a review app"
environment: environment:
name: review/$CI_BUILD_REF_NAME name: review/$CI_BUILD_REF_NAME
url: https://$CI_BUILD_REF_SLUG.example.com url: https://$CI_BUILD_REF_SLUG.review.example.com
only: only:
- branches - branches
except: except:
...@@ -266,9 +273,18 @@ ones. ...@@ -266,9 +273,18 @@ ones.
So, the first part is `review`, followed by a `/` and then `$CI_BUILD_REF_NAME` 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 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 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 URL, we use `$CI_ENVIRONMENT_SLUG` in the `environment:url` so that the
can get a specific and distinct URL for each branch. Again, the way you set up environment can get a specific and distinct URL for each branch. In this case,
the webserver to serve these requests is based on your setup. 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 Last but not least, we tell the job to run [`only`][only] on branches
[`except`][only] master. [`except`][only] master.
...@@ -300,7 +316,7 @@ deploy_review: ...@@ -300,7 +316,7 @@ deploy_review:
- echo "Deploy a review app" - echo "Deploy a review app"
environment: environment:
name: review/$CI_BUILD_REF_NAME name: review/$CI_BUILD_REF_NAME
url: https://$CI_BUILD_REF_SLUG.example.com url: https://$CI_ENVIRONMENT_SLUG.example.com
only: only:
- branches - branches
except: except:
...@@ -419,7 +435,7 @@ deploy_review: ...@@ -419,7 +435,7 @@ deploy_review:
- echo "Deploy a review app" - echo "Deploy a review app"
environment: environment:
name: review/$CI_BUILD_REF_NAME 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 on_stop: stop_review
only: only:
- branches - branches
...@@ -493,10 +509,6 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/* ...@@ -493,10 +509,6 @@ fetch = +refs/environments/*:refs/remotes/origin/environments/*
## Limitations ## 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 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` `environment: name`. If you try to re-use variables defined inside `script`
as part of the environment name, it will not work. as part of the environment name, it will not work.
......
...@@ -52,6 +52,8 @@ version of Runner required. ...@@ -52,6 +52,8 @@ version of Runner required.
| **CI_PROJECT_PATH** | 8.10 | 0.5 | The namespace with project name | | **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_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_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** | 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_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 | | **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used |
......
...@@ -690,7 +690,7 @@ The `stop_review_app` job is **required** to have the following keywords defined ...@@ -690,7 +690,7 @@ The `stop_review_app` job is **required** to have the following keywords defined
#### dynamic environments #### dynamic environments
> [Introduced][ce-6323] in GitLab 8.12 and GitLab Runner 1.6. > [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`. `environment` can also represent a configuration hash with `name` and `url`.
These parameters can use any of the defined [CI variables](#variables) These parameters can use any of the defined [CI variables](#variables)
...@@ -703,15 +703,17 @@ deploy as review app: ...@@ -703,15 +703,17 @@ deploy as review app:
stage: deploy stage: deploy
script: make deploy script: make deploy
environment: environment:
name: review-apps/$CI_BUILD_REF_NAME name: review/$CI_BUILD_REF_NAME
url: https://$CI_BUILD_REF_SLUG.review.example.com/ url: https://$CI_ENVIRONMENT_SLUG.example.com/
``` ```
The `deploy as review app` job will be marked as deployment to dynamically 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` create the `review/$CI_BUILD_REF_NAME` environment, where `$CI_BUILD_REF_NAME`
is an [environment variable][variables] set by the Runner. If for example the is an [environment variable][variables] set by the Runner. The
`deploy as review app` job was run in a branch named `pow`, this environment `$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable
should be accessible under `https://pow.review.example.com/`. 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 This of course implies that the underlying server which hosts the application
is properly configured. is properly configured.
...@@ -720,10 +722,6 @@ The common use case is to create dynamic environments for branches and use them ...@@ -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 as Review Apps. You can see a simple example using Review Apps at
https://gitlab.com/gitlab-examples/review-apps-nginx/. 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 ### artifacts
>**Notes:** >**Notes:**
...@@ -1243,5 +1241,5 @@ CI with various languages. ...@@ -1243,5 +1241,5 @@ CI with various languages.
[ce-6323]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6323 [ce-6323]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6323
[environment]: ../environments.md [environment]: ../environments.md
[ce-6669]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6669 [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 [variables]: ../variables/README.md
[ce-7983]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7983
...@@ -87,6 +87,26 @@ describe Ci::Build, models: true do ...@@ -87,6 +87,26 @@ describe Ci::Build, models: true do
end end
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 describe '#trace' do
it { expect(build.trace).to be_nil } it { expect(build.trace).to be_nil }
...@@ -328,6 +348,22 @@ describe Ci::Build, models: true do ...@@ -328,6 +348,22 @@ describe Ci::Build, models: true do
it { user_variables.each { |v| is_expected.to include(v) } } it { user_variables.each { |v| is_expected.to include(v) } }
end 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 context 'when build started manually' do
before do before do
build.update_attributes(when: :manual) build.update_attributes(when: :manual)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment