diff options
author | James Fargher <proglottis@gmail.com> | 2019-07-18 15:45:12 +1200 |
---|---|---|
committer | James Fargher <proglottis@gmail.com> | 2019-07-19 09:23:07 +1200 |
commit | 01431ae3076370bec1c014e326cdb20b47ae55b1 (patch) | |
tree | de042beee18387364ff8420322b31952822b35c1 | |
parent | 34f5eb1b93b5c1e7d8ed8d578d8b94cd33d2dca3 (diff) | |
download | gitlab-ce-auto_devops_detect2.tar.gz |
Initial detection of Auto-DevOps buildable projectsauto_devops_detect2
-rw-r--r-- | app/models/ci/pipeline.rb | 7 | ||||
-rw-r--r-- | app/models/project.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/auto_devops/buildable_detector.rb | 103 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/validate/config.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/auto_devops/buildable_detector_spec.rb | 36 |
5 files changed, 155 insertions, 3 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 2262282e647..c44f0a42585 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -809,11 +809,16 @@ module Ci def implied_ci_yaml_file return unless project - if project.auto_devops_enabled? + if project.auto_devops_enabled? && auto_devops_buildable? Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content end end + def auto_devops_buildable? + project.has_auto_devops_explicitly_enabled? || + Gitlab::AutoDevops::BuildableDetector.new(project, sha).buildable? + end + def pipeline_data Gitlab::DataBuilder::Pipeline.build(self) end diff --git a/app/models/project.rb b/app/models/project.rb index 2906aca75fc..e3e177c97e2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -665,10 +665,14 @@ class Project < ApplicationRecord if auto_devops&.enabled.nil? has_auto_devops_implicitly_enabled? else - auto_devops.enabled? + has_auto_devops_explicitly_enabled? end end + def has_auto_devops_explicitly_enabled? + auto_devops&.enabled? + end + def has_auto_devops_implicitly_enabled? auto_devops_config = first_auto_devops_config diff --git a/lib/gitlab/auto_devops/buildable_detector.rb b/lib/gitlab/auto_devops/buildable_detector.rb new file mode 100644 index 00000000000..39c3d29135b --- /dev/null +++ b/lib/gitlab/auto_devops/buildable_detector.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Gitlab + module AutoDevops + class BuildableDetector + VARIABLES = [ + 'BUILDPACK_URL' + ].freeze + + FILE_PATTERNS = [ + 'Dockerfile', + + # https://github.com/heroku/heroku-buildpack-clojure + 'project.clj', + + # https://github.com/heroku/heroku-buildpack-go + 'go.mod', + 'Gopkg.mod', + 'Godeps/Godeps.json', + 'vendor/vendor.json', + 'glide.yaml', + 'src/**.go', + + # https://github.com/heroku/heroku-buildpack-gradle + 'gradlew', + 'build.gradle', + 'settings.gradle', + + # https://github.com/heroku/heroku-buildpack-java + 'pom.xml', + 'pom.atom', + 'pom.clj', + 'pom.groovy', + 'pom.rb', + 'pom.scala', + 'pom.yaml', + 'pom.yml', + + # https://github.com/heroku/heroku-buildpack-multi + '.buildpacks', + + # https://github.com/heroku/heroku-buildpack-nodejs + 'package.json', + + # https://github.com/heroku/heroku-buildpack-php + 'composer.json', + 'index.php', + + # https://github.com/heroku/heroku-buildpack-play + # TODO: detect script excludes some scala files + '*/conf/application.conf', + '*modules*', + + # https://github.com/heroku/heroku-buildpack-python + # TODO: detect script checks that all of these exist, not any + 'requirements.txt', + 'setup.py', + 'Pipfile', + + # https://github.com/heroku/heroku-buildpack-ruby + 'Gemfile', + + # https://github.com/heroku/heroku-buildpack-scala + '*.sbt', + 'project/*.scala', + '.sbt/*.scala', + 'project/build.properties', + + # https://github.com/dokku/buildpack-nginx + '.static' + ].freeze + + def initialize(project, ref) + @project = project + @ref = ref + end + + def buildable? + detected_variables? || detected_files? + end + + private + + attr_accessor :project, :ref + + def detected_variables? + project.ci_variables_for(ref: ref).where(key: VARIABLES).exists? + end + + def detected_files? + return unless tree = project.repository.tree(ref) + + tree.blobs.find do |blob| + FILE_PATTERNS.any? do |pattern| + File.fnmatch?(pattern, blob.path, File::FNM_CASEFOLD) + end + end + rescue Gitlab::Git::Repository::NoRepository + # nop + end + end + end +end diff --git a/lib/gitlab/ci/pipeline/chain/validate/config.rb b/lib/gitlab/ci/pipeline/chain/validate/config.rb index 28c38cc3d18..a6f63eabb80 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/config.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/config.rb @@ -11,7 +11,11 @@ module Gitlab def perform! unless @pipeline.config_processor unless @pipeline.ci_yaml_file - return error("Missing #{@pipeline.ci_yaml_file_path} file") + if @pipeline.project.auto_devops_enabled? + return error("Auto-DevOps enabled but no buildable files found") + else + return error("Missing #{@pipeline.ci_yaml_file_path} file") + end end if @command.save_incompleted && @pipeline.has_yaml_errors? diff --git a/spec/lib/gitlab/auto_devops/buildable_detector_spec.rb b/spec/lib/gitlab/auto_devops/buildable_detector_spec.rb new file mode 100644 index 00000000000..42187def844 --- /dev/null +++ b/spec/lib/gitlab/auto_devops/buildable_detector_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::AutoDevops::BuildableDetector do + describe '#buildable?' do + let(:project) { create(:project) } + let(:ref) { :head } + + subject(:detector) { described_class.new(project, ref) } + + context 'no matching variables or files' do + it 'is not buildable' do + expect(detector).to_not be_buildable + end + end + + context 'matching variable' do + before do + create(:ci_variable, project: project, key: 'BUILDPACK_URL') + end + + it 'is buildable' do + expect(detector).to be_buildable + end + end + + context 'matching file' do + let(:project) { create(:project, :custom_repo, files: { 'Dockerfile' => '' }) } + + it 'is buildable' do + expect(detector).to be_buildable + end + end + end +end |