-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add script history #110
Add script history #110
Conversation
app/models/kuroko2/job_definition.rb
Outdated
@@ -30,6 +30,7 @@ module PreventMultiStatus | |||
has_many :job_suspend_schedules, dependent: :delete_all | |||
has_many :job_definition_tags | |||
has_many :tags, through: :job_definition_tags | |||
has_many :revisions, -> { order(:id).reverse_order }, class_name: 'JobDefinitionRevision', dependent: :destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
order(id: :desc)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we will want revision's permalink.
Are there plans to add it? (It is good even after this pull request.)
app/models/kuroko2/job_definition.rb
Outdated
@@ -100,6 +101,12 @@ def create_instance(script: nil, launched_by:, token: nil ) | |||
job_instances.create!(script: script, log_message: message) | |||
end | |||
|
|||
def record_revision(user: nil) | |||
unless revisions.first.try(:script) == script | |||
Kuroko2::JobDefinitionRevision.create(job_definition: self, script: script, user: user, changed_at: Time.now) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kuroko2 needs to follow Rails time zone configuration. Please use Time.zone.now
.
app/models/kuroko2/job_definition.rb
Outdated
@@ -30,6 +30,7 @@ module PreventMultiStatus | |||
has_many :job_suspend_schedules, dependent: :delete_all | |||
has_many :job_definition_tags | |||
has_many :tags, through: :job_definition_tags | |||
has_many :revisions, -> { order(id: :desc) }, class_name: 'JobDefinitionRevision', dependent: :destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JobDefinition model already has a version
column. It may be confusing.
Possible options are as follows, I think.
- Remove JobDefinition's
revision
column. - A JobDefinitionRevision has JobDefinition's
revision
column.
I think No.1 is better. What do you think?
@@ -16,6 +16,7 @@ def create_resource | |||
user.stars.create(job_definition: definition) if user.google_account? | |||
end | |||
|
|||
definition.record_revision |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may do it in JobDefinition's after_save
.
reviewable pr? 🤔 |
59a28c2
to
74841d6
Compare
t.belongs_to :job_definition, foreign_key: true, null: false | ||
t.text :script, null: false | ||
t.belongs_to :user, foreign_key: true, null: true | ||
t.datetime :changed_at, null: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When does changed_at
become null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Job definitions created before this changes have revision with null changed_at
.
Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using updated_at
as first changed_at
seems reasonable to me, how do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
updated_at
as firstchanged_at
Sorry, I don't understand. What do you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean
Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script)
to
Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script, changed_at: definition.updated_at)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed in 3d7e119.
app/models/kuroko2/job_definition.rb
Outdated
@@ -19,8 +19,6 @@ module PreventMultiStatus | |||
PreventMultiStatus::ERROR => [Kuroko2::Token::FAILURE, Kuroko2::Token::CRITICAL], | |||
} | |||
|
|||
self.locking_column = :version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you disable optimistic locking? http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because version
column has removed.
remove_column :job_definitions, :version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you remove version column...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops... I forgot that JobDefinition using optimistic locking. Please revert the commit 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted the commit (4570e60)
@@ -50,6 +50,7 @@ def create | |||
|
|||
if @definition.save | |||
current_user.stars.create(job_definition: @definition) | |||
@definition.revisions.first.update(user: current_user) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be executed in the same transaction with @definition.save
, I think.
Since revision requires user_id, running record_revision
in after_save hook looks bad idea to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So should I revert 74841d6?
#110 (comment) @eisuke
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be executed in the same transaction with @definition.save
I agree. But I'd like to avoid writing definition.record_revision
in some controllers.
How about adding the #save_and_record_revision(attributes, edited_user: nil)
method to JobDefinition model ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed in debd0db.
end | ||
|
||
Kuroko2::JobDefinition.all.each do |definition| | ||
Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This migration should not be run in rails db:rollback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I fixed in 8cc9ec4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO) This resource will be created when JobDefinition's script changed, hence, JobDefinitionRevision
may be not a good name.
How about just ScriptRevision
?
@@ -100,6 +101,18 @@ def create_instance(script: nil, launched_by:, token: nil ) | |||
job_instances.create!(script: script, log_message: message) | |||
end | |||
|
|||
def save_and_record_revision(edited_user: nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be executed in the same transaction with @definition.save, I think.
Since revision requires user_id, running record_revision in after_save hook looks bad idea to me.
I think @eagletmt means not only make it in one method, but execute in the real transaction
, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed in 1066340.
@@ -0,0 +1,24 @@ | |||
- content_for :title, "##{@definition.id} #{@definition.name} « Job Definitions" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitions -> Definition Revisions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed in bc22e19.
|
||
style= Diffy::CSS | ||
|
||
- @revisions.each.with_index do |revision, i| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(maybe) Use each_cons(2)
instead of this.
then html_diff
doesn't need to allow nil
case, is it right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If using each_cons(2)
, oldest revision will not displayed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, my comment was not proper. I should say why you want to show the oldest revision. (weak opinion)
It's better to use each_with_index(1)
if you let it leave.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Showing the oldest revision explains initial script and who created the definition. I think this is helpful.
spec/dummy/db/schema.rb
Outdated
@@ -10,7 +10,7 @@ | |||
# | |||
# It's strongly recommended that you check this file into your version control system. | |||
|
|||
ActiveRecord::Schema.define(version: 32) do | |||
ActiveRecord::Schema.define(version: 33) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀 many tables seems to be deleted from schema, is this intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted tables were duplicated in schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙈
t.belongs_to :job_definition, foreign_key: true, null: false | ||
t.text :script, null: false | ||
t.belongs_to :user, foreign_key: true, null: true | ||
t.datetime :changed_at, null: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using updated_at
as first changed_at
seems reasonable to me, how do you think?
describe 'changes script' do | ||
let(:script) { "noop:\nnoop:\n" } | ||
it do | ||
expect(response).to redirect_to(assigns(:definition)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent
expect(assigns(:definition).revisions.size).to eq 2 | ||
expect(assigns(:definition).revisions.first.script).to eq script | ||
expect(assigns(:definition).revisions.first.user).to eq controller.current_user | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty line 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I fixed in 12e87fa.
save | ||
end | ||
|
||
def update_and_record_revision(attributes, edited_user: nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really worked in transaction? I don't think so 🤔
L105 seems to work well because job_definition is not saved when script revision assignment occurs.
irb(main):008:0> jd = JobDefinition.last
JobDefinition Load (0.4ms) SELECT `job_definitions`.* FROM `job_definitions` ORDER BY `job_definitions`.`id` DESC LIMIT 1
=> #<JobDefinition id: 1, script: "a", created_at: "2018-04-27 06:42:42", updated_at: "2018-04-27 06:42:42">
irb(main):009:0> jd.assign_attributes(script: 'updated')
=> nil
irb(main):010:0> jd.script_revisions << ScriptRevision.new(script: 'updated')
(0.2ms) BEGIN
ScriptRevision Create (6.1ms) INSERT INTO `script_revisions` (`script`, `job_definition_id`, `created_at`, `updated_at`) VALUES ('updated', 1, '2018-04-27 06:47:05', '2018-04-27 06:47:05')
(0.5ms) COMMIT
ScriptRevision Load (26.8ms) SELECT `script_revisions`.* FROM `script_revisions` WHERE `script_revisions`.`job_definition_id` = 1 LIMIT 11
=> #<ActiveRecord::Associations::CollectionProxy [#<ScriptRevision id: 1, script: "ab", job_definition_id: 1, created_at: "2018-04-27 06:42:42", updated_at: "2018-04-27 06:42:42">, #<ScriptRevision id: 2, script: "ccccc", job_definition_id: 1, created_at: "2018-04-27 06:43:15", updated_at: "2018-04-27 06:43:15">, #<ScriptRevision id: 3, script: "ccbsadf", job_definition_id: 1, created_at: "2018-04-27 06:43:34", updated_at: "2018-04-27 06:43:34">, #<ScriptRevision id: 4, script: "updated", job_definition_id: 1, created_at: "2018-04-27 06:47:05", updated_at: "2018-04-27 06:47:05">]>
irb(main):011:0> jd.save
(0.2ms) BEGIN
JobDefinition Update (6.8ms) UPDATE `job_definitions` SET `script` = 'updated', `updated_at` = '2018-04-27 06:47:18' WHERE `job_definitions`.`id` = 1
(0.8ms) COMMIT
=> true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed in dbb501e.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM XD
There is the problem that tables has different type of primary key from its installed: - installed before 0.2.0: use unsigned int for primary key - installed after 0.2.0: use signed int for primary key This problem was maden by fa75b20. This makes hard to keep consistency of code / infra. For instance, we need to care about 2 types of primary when adding foreign key. Actually, this problem already occured at cookpad#110 To solve the problem, this patch proposes to alter these primary key to bigint, which is next default type of rails.
There is the problem that some tables has different type of primary key from its installed: - before 0.2.0: using unsigned int for primary key - after 0.2.0: using signed int for primary key This problem was made by fa75b20. This makes hard to keep consistency of code / infra. For instance, we need to care about 2 types of primary when adding foreign key. Actually, this is already blocker of cookpad#110 To solve the problem, this patch proposes to alter these primary key to bigint, which is next default type of rails.
There is the problem that some tables has different type of primary key from its installed: - before 0.2.0: using unsigned int for primary key - after 0.2.0: using signed int for primary key This problem was made by fa75b20. This makes hard to keep consistency of code / infra. For instance, we need to care about 2 types of primary when adding foreign key. Actually, this is already blocker of cookpad#110 To solve the problem, this patch proposes to alter these primary key to bigint, which is next default type of rails.
There is the problem that some tables has different type of primary key from its installed: - before 0.2.0: using unsigned int for primary key - after 0.2.0: using signed int for primary key This problem was made by fa75b20. This makes hard to keep consistency of code / infra. For instance, we need to care about 2 types of primary when adding foreign key. Actually, this is already blocker of cookpad#110 To solve the problem, this patch proposes to alter these primary key to bigint, which is next default type of rails.
There is the problem that some tables has different type of primary key from its installed: - before 0.2.0: using unsigned int for primary key - after 0.2.0: using signed int for primary key This problem was made by fa75b20. This makes hard to keep consistency of code / infra. For instance, we need to care about 2 types of primary when adding foreign key. Actually, this is already blocker of cookpad#110 To solve the problem, this patch proposes to alter these primary key to bigint, which is next default type of rails.
#117 is merged, could you update this pr? :) |
dbb501e
to
c6130ed
Compare
Rebased |
👍 Give me some more time to merge |
Thanks!!! XD |
Add page to show script revisions.