From e6cbd626845ee3436fdcf36b087fd1de894804a0 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 20 Jul 2016 00:08:54 +0200 Subject: [PATCH] Update all exposed variables to CI builds --- app/models/ci/build.rb | 23 +++- doc/ci/variables/README.md | 17 ++- spec/models/build_spec.rb | 197 ++++++++++++++++++---------- spec/requests/ci/api/builds_spec.rb | 10 +- 4 files changed, 160 insertions(+), 87 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index cc4809b3abe..6115ffd87c2 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -451,7 +451,7 @@ module Ci variables << { key: 'CI', value: 'true', public: true } variables << { key: 'GITLAB_CI', value: 'true', public: true } - variables << { key: 'CI_BUILD_ID', value: id, public: true } + variables << { key: 'CI_BUILD_ID', value: id.to_s, public: true } variables << { key: 'CI_BUILD_TOKEN', value: token, public: false } variables << { key: 'CI_BUILD_REF', value: sha, public: true } variables << { key: 'CI_BUILD_BEFORE_SHA', value: before_sha, public: true } @@ -461,21 +461,32 @@ module Ci variables << { key: 'CI_BUILD_STAGE', value: stage, public: true } variables << { key: 'CI_BUILD_TRIGGERED', value: 'true', public: true } if trigger_request - variables << { key: 'CI_PIPELINE_ID', value: pipeline.id, public: true } + variables << { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true } - variables << { key: 'CI_PROJECT_ID', value: project_id, public: true } + variables << { key: 'CI_PROJECT_ID', value: project.id.to_s, public: true } variables << { key: 'CI_PROJECT_NAME', value: project.path, public: true } variables << { key: 'CI_PROJECT_PATH', value: project.path_with_namespace, public: true } variables << { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.path, public: true } variables << { key: 'CI_PROJECT_URL', value: project.web_url, public: true } - variables << { key: 'CI_REGISTRY', value: Gitlab.config.registry.host_port, public: true } if Gitlab.config.registry.enabled - variables << { key: 'CI_REGISTRY_IMAGE', value: project.container_registry_repository_url, public: true } if project.container_registry_repository_url + if Gitlab.config.registry.enabled + variables << { key: 'CI_REGISTRY', value: Gitlab.config.registry.host_port, public: true } + + if project.container_registry_enabled? + variables << { key: 'CI_REGISTRY_IMAGE', value: project.container_registry_repository_url, public: true } + end + end variables << { key: 'CI_SERVER_NAME', value: 'GitLab', public: true } variables << { key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true } variables << { key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true } - variables << { key: 'CI_SERVER_URL', value: Gitlab::REVISION, public: true } + + if runner + variables << { key: 'CI_RUNNER_ID', value: runner.id.to_s, public: true } + variables << { key: 'CI_RUNNER_DESCRIPTION', value: runner.description, public: true } + variables << { key: 'CI_RUNNER_TAGS', value: runner.tag_list.to_s, public: true } + end + variables end diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 3683470b54c..6fb164e950b 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -35,15 +35,18 @@ The `API_TOKEN` will take the Secure Variable value: `SECURE`. | **CI_BUILD_REPO** | all | all | The URL to clone the Git repository | | **CI_BUILD_TRIGGERED** | all | 0.5 | The flag to indicate that build was [triggered] | | **CI_BUILD_TOKEN** | all | 1.2 | Token used for authenticating with the GitLab Container Registry | -| **CI_PIPELINE_ID** | 8.9 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally | +| **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally | | **CI_PROJECT_ID** | all | all | The unique id of the current project that GitLab CI uses internally | -| **CI_PROJECT_NAME** | 8.9 | 0.5 | The project name that is currently build | -| **CI_PROJECT_NAMESPACE**| 8.9 | 0.5 | The project namespace that is currently build | -| **CI_PROJECT_PATH** | 8.9 | 0.5 | The namespace with project name | -| **CI_PROJECT_URL** | 8.9 | 0.5 | The HTTP address to access project | +| **CI_PROJECT_NAME** | 8.10 | 0.5 | The project name that is currently build | +| **CI_PROJECT_NAMESPACE**| 8.10 | 0.5 | The project namespace that is currently build | +| **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 ran | -| **CI_REGISTRY** | 8.9 | 0.5 | If the Container Registry is enabled it returns address of GitLab's Container Registry | -| **CI_REGISTRY_IMAGE** | 8.9 | 0.5 | If the Container Registry is for project it returns the address of registry tied to specific project | +| **CI_REGISTRY** | 8.10 | 0.5 | If the Container Registry is enabled it returns address of GitLab's Container Registry | +| **CI_REGISTRY_IMAGE** | 8.10 | 0.5 | If the Container Registry is for project it returns the address of registry tied to specific project | +| **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of the used runner | +| **CI_RUNNER_DESCRIPTION** | 8.10 | 0.5 | The description of runners as saved in GitLab | +| **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags | **Some of the variables are only available when using runner with at least defined version.** diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 06d984c7a40..796f39c1aa3 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -191,79 +191,87 @@ describe Ci::Build, models: true do end describe '#variables' do + let(:container_registry_enabled) { false } let(:predefined_variables) do [ - { key: :CI_BUILD_NAME, value: 'test', public: true }, - { key: :CI_BUILD_STAGE, value: 'test', public: true }, + { key: 'CI', value: 'true', public: true }, + { key: 'GITLAB_CI', value: 'true', public: true }, + { key: 'CI_BUILD_ID', value: build.id.to_s, public: true }, + { key: 'CI_BUILD_TOKEN', value: build.token, public: false }, + { key: 'CI_BUILD_REF', value: build.sha, public: true }, + { key: 'CI_BUILD_BEFORE_SHA', value: build.before_sha, public: true }, + { key: 'CI_BUILD_REF_NAME', value: 'master', public: true }, + { key: 'CI_BUILD_NAME', value: 'test', public: true }, + { key: 'CI_BUILD_STAGE', value: 'test', public: true }, + { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true }, + { key: 'CI_PROJECT_ID', value: project.id.to_s, public: true }, + { key: 'CI_PROJECT_NAME', value: project.path, public: true }, + { key: 'CI_PROJECT_PATH', value: project.path_with_namespace, public: true }, + { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.path, public: true }, + { key: 'CI_PROJECT_URL', value: project.web_url, public: true }, + { key: 'CI_SERVER_NAME', value: 'GitLab', public: true }, + { key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true }, + { key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true } ] end + before do + stub_container_registry_config(enabled: container_registry_enabled, host_port: 'registry.example.com') + end + subject { build.variables } context 'returns variables' do - let(:yaml_variables) do - [ - { key: :DB_NAME, value: 'postgres', public: true } - ] + before do + build.yaml_variables = [] + end + + it { is_expected.to eq(predefined_variables) } + end + + context 'when build is for tag' do + let(:tag_variable) do + { key: 'CI_BUILD_TAG', value: 'master', public: true } end before do - build.yaml_variables = yaml_variables + build.update_attributes(tag: true) end - it { is_expected.to eq(predefined_variables + yaml_variables) } - - context 'for tag' do - let(:tag_variable) do - [ - { key: :CI_BUILD_TAG, value: 'master', public: true } - ] - end - - before do - build.update_attributes(tag: true) - end - - it { is_expected.to eq(tag_variable + predefined_variables + yaml_variables) } - end - - context 'and secure variables' do - let(:secure_variables) do - [ - { key: 'SECRET_KEY', value: 'secret_value', public: false } - ] - end - - before do - build.project.variables << Ci::Variable.new(key: 'SECRET_KEY', value: 'secret_value') - end - - it { is_expected.to eq(predefined_variables + yaml_variables + secure_variables) } - - context 'and trigger variables' do - let(:trigger) { create(:ci_trigger, project: project) } - let(:trigger_request) { create(:ci_trigger_request_with_variables, pipeline: pipeline, trigger: trigger) } - let(:trigger_variables) do - [ - { key: :TRIGGER_KEY, value: 'TRIGGER_VALUE', public: false } - ] - end - let(:predefined_trigger_variable) do - [ - { key: :CI_BUILD_TRIGGERED, value: 'true', public: true } - ] - end - - before do - build.trigger_request = trigger_request - end - - it { is_expected.to eq(predefined_variables + predefined_trigger_variable + yaml_variables + secure_variables + trigger_variables) } - end - end + it { is_expected.to include(tag_variable) } end - context 'when yaml_variables is undefined' do + context 'when secure variable is defined' do + let(:secure_variable) do + { key: 'SECRET_KEY', value: 'secret_value', public: false } + end + + before do + build.project.variables << Ci::Variable.new(key: 'SECRET_KEY', value: 'secret_value') + end + + it { is_expected.to include(secure_variable) } + end + + context 'when build is for triggers' do + let(:trigger) { create(:ci_trigger, project: project) } + let(:trigger_request) { create(:ci_trigger_request_with_variables, pipeline: pipeline, trigger: trigger) } + let(:user_trigger_variable) do + { key: :TRIGGER_KEY, value: 'TRIGGER_VALUE', public: false } + end + let(:predefined_trigger_variable) do + { key: 'CI_BUILD_TRIGGERED', value: 'true', public: true } + end + + before do + build.trigger_request = trigger_request + end + + it { is_expected.to include(user_trigger_variable) } + it { is_expected.to include(predefined_trigger_variable) } + end + + context 'when yaml_variables are undefined' do before do build.yaml_variables = nil end @@ -282,10 +290,10 @@ describe Ci::Build, models: true do context 'if config does not have a questioned job' do let(:config) do YAML.dump({ - test_other: { - script: 'Hello World' - } - }) + test_other: { + script: 'Hello World' + } + }) end it { is_expected.to eq(predefined_variables) } @@ -294,13 +302,13 @@ describe Ci::Build, models: true do context 'if config has variables' do let(:config) do YAML.dump({ - test: { - script: 'Hello World', - variables: { - KEY: 'value' - } - } - }) + test: { + script: 'Hello World', + variables: { + KEY: 'value' + } + } + }) end let(:variables) do [{ key: :KEY, value: 'value', public: true }] @@ -310,6 +318,57 @@ describe Ci::Build, models: true do end end end + + context 'when container registry is enabled' do + let(:container_registry_enabled) { true } + let(:ci_registry) do + { key: 'CI_REGISTRY', value: 'registry.example.com', public: true} + end + let(:ci_registry_image) do + { key: 'CI_REGISTRY_IMAGE', value: project.container_registry_repository_url, public: true} + end + + context 'and is disabled for project' do + before do + project.update(container_registry_enabled: false) + end + + it { is_expected.to include(ci_registry) } + it { is_expected.not_to include(ci_registry_image) } + end + + context 'and is enabled for project' do + before do + project.update(container_registry_enabled: true) + end + + it { is_expected.to include(ci_registry) } + it { is_expected.to include(ci_registry_image) } + end + end + + context 'when runner is assigned to build' do + let(:runner) { create(:ci_runner, description: 'description', tag_list: ['docker', 'linux']) } + + before do + build.update(runner: runner) + end + + it { is_expected.to include({ key: 'CI_RUNNER_ID', value: runner.id.to_s, public: true }) } + it { is_expected.to include({ key: 'CI_RUNNER_DESCRIPTION', value: 'description', public: true }) } + it { is_expected.to include({ key: 'CI_RUNNER_TAGS', value: 'docker, linux', public: true }) } + end + + context 'returns variables in valid order' do + before do + allow(build).to receive(:predefined_variables) { ['predefined'] } + allow(build).to receive(:yaml_variables) { ['yaml variables'] } + allow(build).to receive(:project_variables) { ['secure variables'] } + allow(build).to receive(:trigger_variables) { ['trigger variables'] } + end + + it { is_expected.to eq(['predefined', 'yaml variables', 'secure variables', 'trigger variables']) } + end end describe '#has_tags?' do diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index e7cbc3dd3a7..1c7c60ec644 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -73,12 +73,12 @@ describe Ci::API::API do post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin } expect(response).to have_http_status(201) - expect(json_response["variables"]).to eq([ + expect(json_response["variables"]).to include( { "key" => "CI_BUILD_NAME", "value" => "spinach", "public" => true }, { "key" => "CI_BUILD_STAGE", "value" => "test", "public" => true }, { "key" => "DB_NAME", "value" => "postgres", "public" => true }, { "key" => "SECRET_KEY", "value" => "secret_value", "public" => false } - ]) + ) end it "returns variables for triggers" do @@ -92,14 +92,14 @@ describe Ci::API::API do post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin } expect(response).to have_http_status(201) - expect(json_response["variables"]).to eq([ + expect(json_response["variables"]).to include( { "key" => "CI_BUILD_NAME", "value" => "spinach", "public" => true }, { "key" => "CI_BUILD_STAGE", "value" => "test", "public" => true }, { "key" => "CI_BUILD_TRIGGERED", "value" => "true", "public" => true }, { "key" => "DB_NAME", "value" => "postgres", "public" => true }, { "key" => "SECRET_KEY", "value" => "secret_value", "public" => false }, - { "key" => "TRIGGER_KEY", "value" => "TRIGGER_VALUE", "public" => false }, - ]) + { "key" => "TRIGGER_KEY", "value" => "TRIGGER_VALUE", "public" => false } + ) end it "returns dependent builds" do