diff options
author | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-09-06 11:39:26 +0200 |
---|---|---|
committer | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-09-06 11:39:32 +0200 |
commit | 29a10bade191fc64124d6115a5877e8c32997268 (patch) | |
tree | e7f98bb33a7b8ba8dc9334423a45b2e708d0dd9e | |
parent | ad599eb65c8ce483a7faaffe226ec7ce53da0f55 (diff) | |
download | gitlab-ce-zj-deployed-time-ago.tar.gz |
Ground work for deployed ago tooltipzj-deployed-time-ago
[ci skip]
-rw-r--r-- | app/models/deployed_sha.rb | 11 | ||||
-rw-r--r-- | app/models/deployment.rb | 2 | ||||
-rw-r--r-- | app/services/create_deployment_service.rb | 19 | ||||
-rw-r--r-- | app/workers/deployed_sha_worker.rb | 18 | ||||
-rw-r--r-- | db/migrate/20160906064239_create_deployed_shas.rb | 10 | ||||
-rw-r--r-- | db/schema.rb | 10 | ||||
-rw-r--r-- | spec/models/deployed_sha_spec.rb | 7 | ||||
-rw-r--r-- | spec/models/deployment_spec.rb | 1 | ||||
-rw-r--r-- | spec/services/create_deployment_service_spec.rb | 16 | ||||
-rw-r--r-- | spec/workers/deployed_sha_worker_spec.rb | 33 |
10 files changed, 114 insertions, 13 deletions
diff --git a/app/models/deployed_sha.rb b/app/models/deployed_sha.rb new file mode 100644 index 00000000000..8435fa08647 --- /dev/null +++ b/app/models/deployed_sha.rb @@ -0,0 +1,11 @@ +class DeployedSha < ActiveRecord::Base + validates :sha, + presence: true, + uniqueness: { scope: :deployment_id }, + format: { with: /\A\h{6,40}\z/ } + + # A sha is not unique in the database, forks can deploy too + def find_by_sha(project, sha) + raise NotImplementedError + end +end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 1e338889714..7c608647531 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -6,6 +6,8 @@ class Deployment < ActiveRecord::Base belongs_to :user belongs_to :deployable, polymorphic: true + has_many :deployed_shas + validates :sha, presence: true validates :ref, presence: true diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb index efeb9df9527..426fb721cad 100644 --- a/app/services/create_deployment_service.rb +++ b/app/services/create_deployment_service.rb @@ -6,13 +6,16 @@ class CreateDeploymentService < BaseService name: params[:environment] ) - project.deployments.create( - environment: environment, - ref: params[:ref], - tag: params[:tag], - sha: params[:sha], - user: current_user, - deployable: deployable - ) + deployment = project.deployments.create( + environment: environment, + ref: params[:ref], + tag: params[:tag], + sha: params[:sha], + user: current_user, + deployable: deployable + ) + + DeployedShaWorker.perform_async(deployment.id) + deployment end end diff --git a/app/workers/deployed_sha_worker.rb b/app/workers/deployed_sha_worker.rb new file mode 100644 index 00000000000..f343bd7ab1d --- /dev/null +++ b/app/workers/deployed_sha_worker.rb @@ -0,0 +1,18 @@ +class DeployedShaWorker + include Sidekiq::Worker + + def perform(deployment_id) + deployment = Deployment.find(deployment_id) + commit = deployment.commit + + # Simple tree traversal, break when we are out of the deployed range + loop do + break unless deployment.includes_commit?(commit) + + deployment.deployed_shas.create(sha: commit.sha) + + commit = commit.parent + break if commit.merge_commit? + end + end +end diff --git a/db/migrate/20160906064239_create_deployed_shas.rb b/db/migrate/20160906064239_create_deployed_shas.rb new file mode 100644 index 00000000000..bfbdefd1570 --- /dev/null +++ b/db/migrate/20160906064239_create_deployed_shas.rb @@ -0,0 +1,10 @@ +class CreateDeployedShas < ActiveRecord::Migration + def change + create_table :deployed_shas do |t| + t.belongs_to :deployment, index: true + t.string :sha, index: true + + # no timestamps needed + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c9023a02c77..1326051f57b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160901141443) do +ActiveRecord::Schema.define(version: 20160906064239) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -359,6 +359,14 @@ ActiveRecord::Schema.define(version: 20160901141443) do add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree + create_table "deployed_shas", force: :cascade do |t| + t.integer "deployment_id" + t.string "sha" + end + + add_index "deployed_shas", ["deployment_id"], name: "index_deployed_shas_on_deployment_id", using: :btree + add_index "deployed_shas", ["sha"], name: "index_deployed_shas_on_sha", using: :btree + create_table "deployments", force: :cascade do |t| t.integer "iid", null: false t.integer "project_id", null: false diff --git a/spec/models/deployed_sha_spec.rb b/spec/models/deployed_sha_spec.rb new file mode 100644 index 00000000000..77fe30a640d --- /dev/null +++ b/spec/models/deployed_sha_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe DeployedSha, type: :model do + it { is_expected.to respond_to(:sha) } + it { is_expected.to validate_presence_of(:sha) } + it { is_expected.to validate_uniqueness_of(:sha).scoped_to(:deployment_id) } +end diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index bfff639ad78..2c74129e430 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -7,6 +7,7 @@ describe Deployment, models: true do it { is_expected.to belong_to(:environment) } it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:deployable) } + it { is_expected.to have_many(:deployed_shas) } it { is_expected.to delegate_method(:name).to(:environment).with_prefix } it { is_expected.to delegate_method(:commit).to(:project) } diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb index 8da2a2b3c1b..32d918b68fa 100644 --- a/spec/services/create_deployment_service_spec.rb +++ b/spec/services/create_deployment_service_spec.rb @@ -57,10 +57,10 @@ describe CreateDeploymentService, services: true do end end end - + describe 'processing of builds' do let(:environment) { nil } - + shared_examples 'does not create environment and deployment' do it 'does not create a new environment' do expect { subject }.not_to change { Environment.count } @@ -99,12 +99,12 @@ describe CreateDeploymentService, services: true do context 'without environment specified' do let(:build) { create(:ci_build, project: project) } - + it_behaves_like 'does not create environment and deployment' do subject { build.success } end end - + context 'when environment is specified' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline, environment: 'production') } @@ -132,4 +132,12 @@ describe CreateDeploymentService, services: true do end end end + + describe 'triggering of calculations of deployed SHAs' do + it 'queues a worker job' do + expect(DeployedShaWorker).to receive(:perform_async) + + subject.execute + end + end end diff --git a/spec/workers/deployed_sha_worker_spec.rb b/spec/workers/deployed_sha_worker_spec.rb new file mode 100644 index 00000000000..80192893cba --- /dev/null +++ b/spec/workers/deployed_sha_worker_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe DeployedShaWorker do + let(:project) { create(:project) } + let(:environment) { create(:environment, project: project) } + + # Hard coded SHAs guarantee that this test will work correctly 2 months from now + let!(:deployment) do + create(:deployment, environment: environment, sha: '1b12f15a11fc6e62177bef08f47bc7b5ce50b141') + end + let!(:deployment1) do + create(:deployment, environment: environment, sha: '6907208d755b60ebeacb2e9dfea74c92c3449a1f') + end + + subject { DeployedShaWorker.new } + + describe "#perform" do + it 'Adds deployed SHAs to the database' do + expect do + subject.perform(deployment.id) + end.to change { deployment.deployed_shas.count }.from(0).to(1) + end + + # https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional + it 'is idempotent' do + subject.perform(deployment.id) + + expect do + subject.perform(deployment.id) + end.not_to change { deployment.deployed_shas } + end + end +end |