From ad4d3a075fc338280baaf6240861c9de7aa312ad Mon Sep 17 00:00:00 2001
From: Kamil Trzcinski <ayufan@ayufan.eu>
Date: Fri, 11 Mar 2016 13:39:11 +0100
Subject: [PATCH] Describe special YAML features: the use of anchors and hidden
 jobs

---
 CHANGELOG                                    |  2 +
 doc/ci/yaml/README.md                        | 71 ++++++++++++++++++++
 lib/ci/gitlab_ci_yaml_processor.rb           |  2 +
 spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 29 ++++++++
 4 files changed, 104 insertions(+)

diff --git a/CHANGELOG b/CHANGELOG
index 1847c5193a..66675e3942 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,8 @@ v 8.6.0 (unreleased)
   - Return empty array instead of 404 when commit has no statuses in commit status API
   - Decrease the font size and the padding of the `.anchor` icons used in the README (Roberto Dip)
   - Rewrite logo to simplify SVG code (Sean Lang)
+  - Allow to use YAML anchors when parsing the `.gitlab-ci.yml` (Pascal Bach)
+  - Ignore jobs that start with `.` (hidden jobs)
   - Add support for cross-project label references
   - Update documentation to reflect Guest role not being enforced on internal projects
   - Allow search for logged out users
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 051eaa0415..ec57ac5789 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -509,6 +509,77 @@ rspec:
 The cache is provided on best effort basis, so don't expect that cache will be
 always present. For implementation details please check GitLab Runner.
 
+## Special features
+
+It's possible special YAML features like anchors and map merging.
+Thus allowing to greatly reduce the complexity of `.gitlab-ci.yml`.
+
+#### Anchors
+
+You can read more about YAML features [here](https://learnxinyminutes.com/docs/yaml/).
+
+```yaml
+.job_template: &job_definition
+  image: ruby:2.1
+  services:
+    - postgres
+    - redis
+
+test1:
+  << *job_definition
+  script:
+    - test project
+
+test2:
+  << *job_definition
+  script:
+    - test project
+```
+
+The above example uses anchors and map merging.
+It will create a two jobs: `test1` and `test2` that will have the parameters of `.job_template` and custom `script` defined.
+
+```yaml
+.job_template: &job_definition
+  script:
+    - test project
+
+.postgres_services:
+  services: &postgres_definition
+    - postgres
+    - ruby
+
+.mysql_services: 
+  services: &mysql_definition
+    - mysql
+    - ruby
+
+test:postgres:
+  << *job_definition
+  services: *postgres_definition
+
+test:mysql:
+  << *job_definition
+  services: *mysql_definition
+```
+
+The above example uses anchors to define two set of services.
+It will create a two jobs: `test:postgres` and `test:mysql` that will have the script defined in `.job_template`
+and one, the service defined in `.postgres_services` and second the services defined in `.mysql_services`.
+
+### Hidden jobs
+
+The jobs that start with `.` will be not processed by GitLab.
+
+Example of such hidden jobs:
+```yaml
+.job_name:
+  script:
+    - rake spec
+```
+
+The `.job_name` will be ignored. You can use this feature to ignore jobs, or use them as templates with special YAML features.
+
 ## Validate the .gitlab-ci.yml
 
 Each instance of GitLab CI has an embedded debug tool called Lint.
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index 1a3f662811..8ece73eec0 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -60,6 +60,7 @@ module Ci
 
       @jobs = {}
       @config.each do |key, job|
+        next if key.to_s.start_with?('.')
         stage = job[:stage] || job[:type] || DEFAULT_STAGE
         @jobs[key] = { stage: stage }.merge(job)
       end
@@ -81,6 +82,7 @@ module Ci
           services: job[:services] || @services,
           artifacts: job[:artifacts],
           cache: job[:cache] || @cache,
+          dependencies: job[:dependencies],
         }.compact
       }
     end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index f3394910c5..665a65fe35 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -427,6 +427,35 @@ module Ci
       end
     end
 
+    describe "Hidden jobs" do
+      let(:config) do
+        YAML.dump({
+                    '.hidden_job' => { script: 'test' },
+                    'normal_job' => { script: 'test' }
+                  })
+      end
+
+      let(:config_processor) { GitlabCiYamlProcessor.new(config) }
+
+      subject { config_processor.builds_for_stage_and_ref("test", "master") }
+
+      it "doesn't create jobs that starts with dot" do
+        expect(subject.size).to eq(1)
+        expect(subject.first).to eq({
+          except: nil,
+          stage: "test",
+          stage_idx: 1,
+          name: :normal_job,
+          only: nil,
+          commands: "\ntest",
+          tag_list: [],
+          options: {},
+          when: "on_success",
+          allow_failure: false
+        })
+      end
+    end
+
     describe "Error handling" do
       it "fails to parse YAML" do
         expect{GitlabCiYamlProcessor.new("invalid: yaml: test")}.to raise_error(Psych::SyntaxError)
-- 
2.30.9