codebuild-notifier 0.3.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89562832b7f9855d266d8b5bee997da127a0922999f430ea2e8fe08a83bd7927
4
- data.tar.gz: 34068cc500952416033eaa8f3bd8c5ab77b7804078557c53f99e7bdf913a2cd7
3
+ metadata.gz: c165c9da8f00e25f828f0eb5839011c2e28f517289429999a56571c431c766cb
4
+ data.tar.gz: 5b9da99ae167f4ed3e3ce49db33b1f95b738820f5ac9acbacc8c416dd2cec2a9
5
5
  SHA512:
6
- metadata.gz: '01780be2887fd4d76f86700396357d35c4ff26ebb45e683bd3bd7ad17b2ed53320fe5950a26cee11df8086d1779b6f1b54225364438eb9addbc7d71c911e416a'
7
- data.tar.gz: e4e1f33261168a7f71666560bdd2d9f7cf12cd698c35cb3690a54d8f3955e00cacea716457f9b6082942ad9052a92c635484752f8fc0c858997d778fd643c768
6
+ metadata.gz: 9d19c47a78c414223965f09c4221c383aca9faee389b35ec3c924d8603a3ae00076ac9c8b1e9bdae2a01233c46f40facf0076229f5498c4c020ea33e67b8f55d
7
+ data.tar.gz: d4d63e87575aa32907807cd0157df12da2b60fb6c812bdeca407fb2c6306d34dd2be23ae8f361eab4dcf0879ace21d40711fc75378fee2cdaa34a867a34190e5
data/README.md CHANGED
@@ -25,25 +25,28 @@ will come from a user with a name you choose, e.g. CodeBuildBot
25
25
  AWS Secrets Manager instead of the App token.
26
26
 
27
27
  ### DynamoDB table
28
- - expected to be named 'branch-build-status', but can be configured
28
+ - expected to be named 'codebuild-history', but can be configured
29
29
  - the following definition:
30
30
 
31
31
  ```ruby
32
32
  AttributeDefinitions [
33
+ { AttributeName: 'commit_hash', AttributeType: 'S' },
33
34
  { AttributeName: 'source_id', AttributeType: 'S' },
34
- { AttributeName: 'commit_hash', AttributeType: 'S' }
35
+ { AttributeName: 'version_key', AttributeType: 'S' }
35
36
  ]
36
37
  GlobalSecondaryIndexes [
37
38
  {
38
39
  IndexName: 'commit_hash_index',
39
40
  KeySchema: [
40
- { AttributeName: 'commit_hash', KeyType: 'HASH' }
41
+ { AttributeName: 'commit_hash', KeyType: 'HASH' },
42
+ { AttributeName: 'version_key', KeyType: 'RANGE' }
41
43
  ],
42
- Projection: { ProjectionType: 'ALL' },
44
+ Projection: { ProjectionType: 'ALL' }
43
45
  }
44
46
  ]
45
47
  KeySchema [
46
- { AttributeName: 'source_id', KeyType: 'HASH' }
48
+ { AttributeName: 'source_id', KeyType: 'HASH' },
49
+ { AttributeName: 'version_key', KeyType: 'RANGE' }
47
50
  ]
48
51
  ```
49
52
 
@@ -72,8 +75,8 @@ name:
72
75
  ],
73
76
  "Effect": "Allow",
74
77
  "Resource": [
75
- "arn:aws:dynamodb:<your-region>:<your-account-id>:table/branch-build-status",
76
- "arn:aws:dynamodb:<your-region>:<your-account-id>:table/branch-build-status/*"
78
+ "arn:aws:dynamodb:<your-region>:<your-account-id>:table/codebuild-history",
79
+ "arn:aws:dynamodb:<your-region>:<your-account-id>:table/codbuild-history/*"
77
80
  ]
78
81
  },
79
82
  {
@@ -221,7 +224,7 @@ phases:
221
224
  <nobr>--dynamo-table</nobr>
222
225
  </td>
223
226
  <td>
224
- branch-build-status
227
+ codebuild-history
225
228
  </td>
226
229
  <td>
227
230
  This table must be created and permissions granted to it as described
@@ -287,7 +290,7 @@ phases:
287
290
  <nobr>--whitelist-branches</nobr>
288
291
  </td>
289
292
  <td>
290
- master,release
293
+ master
291
294
  </td>
292
295
  <td>
293
296
  Normally statuses will be stored and notifications sent only for builds
@@ -122,17 +122,16 @@ end.parse!
122
122
  config = CodeBuildNotifier::Config.new(command_line_opts)
123
123
  build = CodeBuildNotifier::CurrentBuild.new
124
124
  history = CodeBuildNotifier::BuildHistory.new(config, build)
125
-
126
125
  last_build = history.last_entry
127
126
  build.previous_build = last_build
128
127
 
129
128
  if build.launched_by_retry?
130
129
  # Whenever a build is triggered by a PR or whitelisted branch, we update
131
- # the record for that trigger with the commit hash. If a build is then
132
- # launched using Retry, the status is updated and are notifications sent
133
- # only if the re-tried build was for the latest commit. Otherwise re-trying
134
- # an older commit could result in inaccurate notifications.
135
- quit(not_latest_commit_in_branch_message(build, config)) unless last_build
130
+ # the record for that trigger with the commit hash. If a build is
131
+ # launched using Retry, and there is no history entry for the current
132
+ # commit hash, then the build is not for a PR or a whitelisted branch,
133
+ # and should not be tracked.
134
+ quit(not_pr_or_whitelisted_branch_message(config)) unless last_build
136
135
  else
137
136
  # We only want to track information for whitelisted branches and branches
138
137
  # with open Pull Requests.
@@ -141,8 +140,6 @@ else
141
140
  end
142
141
  end
143
142
 
144
- # Update record for this project + branch/pr in DynamoDb even if the
145
- # status hasn't changed, so the latest commit hash is stored.
146
143
  history.write_entry(build.source_id) do |new_item|
147
144
  cb_puts "Updating dynamo table #{config.dynamo_table} with: #{new_item}"
148
145
  end
@@ -16,9 +16,12 @@
16
16
  # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  require 'codebuild-notifier/config'
19
+ require 'codebuild-notifier/dynamo_base'
20
+ require 'codebuild-notifier/branch_entry'
19
21
  require 'codebuild-notifier/build_history'
20
22
  require 'codebuild-notifier/current_build'
21
23
  require 'codebuild-notifier/git'
24
+ require 'codebuild-notifier/project_summary'
22
25
  require 'codebuild-notifier/slack_message'
23
26
  require 'codebuild-notifier/slack_sender'
24
27
  require 'codebuild-notifier/version'
@@ -0,0 +1,54 @@
1
+ # codebuild-notifier
2
+ # Copyright © 2018 Adam Alboyadjian <adam@cassia.tech>
3
+ # Copyright © 2018 Vista Higher Learning, Inc.
4
+ #
5
+ # codebuild-notifier is free software: you can redistribute it
6
+ # and/or modify it under the terms of the GNU General Public
7
+ # License as published by the Free Software Foundation, either
8
+ # version 3 of the License, or (at your option) any later version.
9
+ #
10
+ # codebuild-notifier is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'digest'
19
+
20
+ module CodeBuildNotifier
21
+ class BranchEntry < DynamoBase
22
+ # Creates entries in a partition key with hardcoded primary key.
23
+ # Within the partition key, there is one record for each github repo.
24
+ # The 'projects' field in that record is a Map data type, keyed off
25
+ # project code, containing the status of the last build for that code.
26
+ def update
27
+ updates = hash_to_dynamo_update(branch_entry).merge(
28
+ key: { source_id: source_id, version_key: version_key }
29
+ )
30
+ yield updates if block_given?
31
+ update_item(updates)
32
+ end
33
+
34
+ private def branch_entry
35
+ {
36
+ branch_name: current_build.branch_name,
37
+ build_id: current_build.build_id,
38
+ commit_hash: source_id,
39
+ git_repo_url: current_build.git_repo_url,
40
+ source_ref: current_build.source_ref,
41
+ status: current_build.status,
42
+ timestamp: current_build.start_time.to_i
43
+ }
44
+ end
45
+
46
+ private def source_id
47
+ current_build.project_code
48
+ end
49
+
50
+ private def version_key
51
+ Digest::MD5.hexdigest(current_build.source_ref)
52
+ end
53
+ end
54
+ end
@@ -15,74 +15,94 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
- require 'active_support'
19
- require 'active_support/core_ext'
20
- require 'aws-sdk-dynamodb'
21
- require 'hashie'
22
-
23
18
  module CodeBuildNotifier
24
- class BuildHistory
25
- attr_reader :config, :current_build
26
-
27
- delegate :dynamo_table, to: :config
19
+ class BuildHistory < DynamoBase
28
20
  delegate :branch_name, :launched_by_retry?, to: :current_build
29
21
 
30
- def initialize(config, current_build)
31
- @config = config
32
- @current_build = current_build
33
- end
34
-
35
22
  def last_entry
23
+ return @last_entry if defined?(@last_entry)
36
24
  # If this build was launched using the Retry command from the console
37
25
  # or api we don't have a Pull Request or branch name to use in the
38
26
  # primary key, so we query by commit hash and project instead.
39
- item = launched_by_retry? ? find_by_commit_and_project : find_by_id
27
+ item = launched_by_retry? ? find_by_commit : find_by_id
40
28
 
41
29
  # Provide .dot access to hash values from Dynamo item.
42
- item && Hashie::Mash.new(item)
30
+ @last_entry = item && Hashie::Mash.new(item)
43
31
  end
44
32
 
45
33
  def write_entry(source_id)
46
34
  updates = hash_to_dynamo_update(new_entry).merge(
47
- key: { source_id: source_id }
35
+ key: { source_id: source_id, version_key: version_key }
48
36
  )
49
37
 
50
38
  yield updates if block_given?
51
39
 
52
- dynamo_client.update_item(
53
- updates.merge(table_name: dynamo_table)
54
- )
40
+ update_item(updates)
41
+
42
+ ProjectSummary.new(config, current_build).update
43
+ BranchEntry.new(config, current_build).update
55
44
  end
56
45
 
57
46
  # The commit hash and project code are used to find which Pull Request
58
47
  # or branch the current build belongs to, and the previous build status
59
48
  # for that Pull Request or branch.
60
- private def find_by_commit_and_project
61
- dynamo_client.query(
62
- expression_attribute_values: {
63
- ':commit_hash' => current_build.commit_hash,
64
- ':project_code' => current_build.project_code
65
- },
66
- filter_expression: 'project_code = :project_code',
49
+ private def find_by_commit
50
+ find_latest_version(
51
+ expression_attribute_values: commit_values,
52
+ filter_expression: commit_filter,
67
53
  index_name: 'commit_hash_index',
68
- key_condition_expression: 'commit_hash = :commit_hash',
69
- table_name: dynamo_table
70
- ).items.first
54
+ key_condition_expression: 'commit_hash = :commit_hash'
55
+ )
56
+ end
57
+
58
+ # When searching by commit hash, if the current build source version
59
+ # is for a PR, only return commits with that PR as the source ref.
60
+ # If source version is not for a pr, only return source refs beginning
61
+ # with branch/. This helps protect against the edge case where the same
62
+ # commit appears in two different PRs, or in a PR and whitelisted branch
63
+ # besides than the PR head.
64
+ private def commit_values
65
+ source_ref_val = if current_build.for_pr?
66
+ current_build.source_version
67
+ else
68
+ 'branch/'
69
+ end
70
+ {
71
+ ':commit_hash' => current_build.commit_hash,
72
+ ':project_code' => current_build.project_code,
73
+ ':source_ref' => source_ref_val
74
+ }
75
+ end
76
+
77
+ private def commit_filter
78
+ source_ref_condition = if current_build.for_pr?
79
+ 'source_ref = :source_ref'
80
+ else
81
+ 'begins_with(source_ref, :source_ref)'
82
+ end
83
+ "project_code = :project_code AND #{source_ref_condition}"
71
84
  end
72
85
 
73
86
  private def find_by_id
74
- dynamo_client.get_item(
75
- key: { 'source_id' => current_build.source_id },
76
- table_name: dynamo_table
77
- ).item
87
+ find_latest_version(
88
+ expression_attribute_values: {
89
+ ':source_id' => current_build.source_id
90
+ },
91
+ key_condition_expression: 'source_id = :source_id'
92
+ )
93
+ end
94
+
95
+ private def find_latest_version(args)
96
+ dynamo_client.query(
97
+ args.merge(
98
+ scan_index_forward: false, # Reverse sort by range key
99
+ table_name: dynamo_table
100
+ )
101
+ ).items.first
78
102
  end
79
103
 
80
104
  private def new_entry
81
- {
82
- commit_hash: current_build.commit_hash,
83
- project_code: current_build.project_code,
84
- status: current_build.status
85
- }.tap do |memo|
105
+ current_build.history_fields.tap do |memo|
86
106
  # If launched via manual re-try instead of via a webhook, we don't
87
107
  # want to overwrite the current source_ref value that tells us which
88
108
  # branch or pull request originally created the dynamo record.
@@ -93,21 +113,16 @@ module CodeBuildNotifier
93
113
  end
94
114
  end
95
115
 
96
- private def hash_to_dynamo_update(hash)
97
- update = hash.each_with_object(
98
- expression_attribute_names: {},
99
- expression_attribute_values: {},
100
- update_expression: []
101
- ) do |(key, value), memo|
102
- memo[:expression_attribute_names]["##{key}"] = key.to_s
103
- memo[:expression_attribute_values][":#{key}"] = value
104
- memo[:update_expression] << "##{key} = :#{key}"
116
+ # The first component of the version_key is the timestamp for the
117
+ # first build of the current commit hash. The second component
118
+ # is the timestamp for the current build. This allows easily finding
119
+ # either the latest commit, or the latest re-build of a commit.
120
+ private def version_key
121
+ if launched_by_retry?
122
+ "#{last_entry.start_time}_#{current_build.start_time}"
123
+ else
124
+ "#{current_build.start_time}_#{current_build.start_time}"
105
125
  end
106
- update.merge(update_expression: "SET #{update[:update_expression].join(', ')}")
107
- end
108
-
109
- private def dynamo_client
110
- @dynamo_client || Aws::DynamoDB::Client.new(region: config.region)
111
126
  end
112
127
  end
113
128
  end
@@ -17,7 +17,7 @@
17
17
 
18
18
  module CodeBuildNotifier
19
19
  class Config
20
- DEFAULT_WHITELIST = %w[master release]
20
+ DEFAULT_WHITELIST = %w[master]
21
21
 
22
22
  attr_reader :additional_channel, :default_strategy, :dynamo_table, :region,
23
23
  :slack_admins, :slack_secret_name, :whitelist_branches
@@ -27,7 +27,7 @@ module CodeBuildNotifier
27
27
  def initialize(
28
28
  additional_channel: ENV['CBN_ADDITIONAL_CHANNEL'],
29
29
  default_strategy: ENV['CBN_DEFAULT_NOTIFY_STRATEGY'] || 'fail_or_status_change',
30
- dynamo_table: ENV['CBN_DYNAMO_TABLE'] || 'branch-build-status',
30
+ dynamo_table: ENV['CBN_DYNAMO_TABLE'] || 'codebuild-history',
31
31
  region: ENV['CBN_AWS_REGION'] || ENV['AWS_REGION'],
32
32
  slack_admins: ENV['CBN_SLACK_ADMIN_USERNAMES'],
33
33
  slack_secret_name: ENV['CBN_SLACK_SECRET_NAME'] || 'slack/codebuild',
@@ -17,8 +17,13 @@
17
17
 
18
18
  module CodeBuildNotifier
19
19
  class CurrentBuild
20
- attr_reader :build_id, :commit_hash, :git_repo_url, :status_code, :trigger
21
20
  attr_accessor :previous_build
21
+ attr_reader :build_id, :commit_hash, :git_repo_url, :source_version,
22
+ :start_time, :status_code, :trigger
23
+
24
+ # attrs from git info
25
+ attr_reader :author_email, :author_name, :committer_email, :committer_name,
26
+ :commit_message_subject, :short_hash
22
27
 
23
28
  # Default values are extracted from CODEBUILD_* ENV vars present in each
24
29
  # CodeBuild # job container.
@@ -27,7 +32,9 @@ module CodeBuildNotifier
27
32
  commit_hash: ENV['CODEBUILD_RESOLVED_SOURCE_VERSION'],
28
33
  git_repo: ENV['CODEBUILD_SOURCE_REPO_URL'],
29
34
  head_ref: ENV['CODEBUILD_WEBHOOK_HEAD_REF'],
35
+ start_time: ENV['CODEBUILD_START_TIME'],
30
36
  status_code: ENV['CODEBUILD_BUILD_SUCCEEDING'],
37
+ source_version: ENV['CODEBUILD_SOURCE_VERSION'],
31
38
  trigger: ENV['CODEBUILD_WEBHOOK_TRIGGER']
32
39
  )
33
40
  @build_id = build_id
@@ -35,8 +42,14 @@ module CodeBuildNotifier
35
42
  # Handle repos specified with and without optional .git suffix.
36
43
  @git_repo_url = git_repo.to_s.gsub(/\.git\z/, '')
37
44
  @head_ref = head_ref
45
+ @source_version = source_version
46
+ @start_time = start_time || (Time.now.to_f * 1_000).to_i
38
47
  @status_code = status_code
39
48
  @trigger = trigger
49
+
50
+ @short_hash, @author_name, @author_email,
51
+ @committer_name, @committer_email,
52
+ @commit_message_subject = git_info
40
53
  end
41
54
 
42
55
  # If launched via retry, the webhook head ref env var is blank,
@@ -65,7 +78,7 @@ module CodeBuildNotifier
65
78
  end
66
79
 
67
80
  def for_pr?
68
- %r{^pr/}.match?(trigger.to_s)
81
+ %r{^pr/}.match?(source_version.to_s)
69
82
  end
70
83
 
71
84
  # source_id, the primary key, is a composite of project_code and
@@ -97,5 +110,25 @@ module CodeBuildNotifier
97
110
  trigger
98
111
  end
99
112
  end
113
+
114
+ def history_fields
115
+ {
116
+ author_email: author_email,
117
+ author_name: author_name,
118
+ build_id: build_id,
119
+ commit_hash: commit_hash,
120
+ commit_subject: commit_message_subject,
121
+ committer_email: committer_email,
122
+ committer_name: committer_name,
123
+ git_repo_url: git_repo_url,
124
+ project_code: project_code,
125
+ start_time: start_time,
126
+ status: status
127
+ }
128
+ end
129
+
130
+ private def git_info
131
+ Git.current_commit
132
+ end
100
133
  end
101
134
  end
@@ -0,0 +1,57 @@
1
+ # codebuild-notifier
2
+ # Copyright © 2018 Adam Alboyadjian <adam@cassia.tech>
3
+ # Copyright © 2018 Vista Higher Learning, Inc.
4
+ #
5
+ # codebuild-notifier is free software: you can redistribute it
6
+ # and/or modify it under the terms of the GNU General Public
7
+ # License as published by the Free Software Foundation, either
8
+ # version 3 of the License, or (at your option) any later version.
9
+ #
10
+ # codebuild-notifier is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'active_support'
19
+ require 'active_support/core_ext'
20
+ require 'aws-sdk-dynamodb'
21
+ require 'hashie'
22
+
23
+ module CodeBuildNotifier
24
+ class DynamoBase
25
+ attr_reader :config, :current_build
26
+
27
+ delegate :dynamo_table, to: :config
28
+
29
+ def initialize(config, build)
30
+ @config = config
31
+ @current_build = build
32
+ end
33
+
34
+ private def update_item(updates)
35
+ dynamo_client.update_item(
36
+ updates.merge(table_name: dynamo_table)
37
+ )
38
+ end
39
+
40
+ private def dynamo_client
41
+ @dynamo_client || Aws::DynamoDB::Client.new(region: config.region)
42
+ end
43
+
44
+ private def hash_to_dynamo_update(hash)
45
+ update = hash.each_with_object(
46
+ expression_attribute_names: {},
47
+ expression_attribute_values: {},
48
+ update_expression: []
49
+ ) do |(key, value), memo|
50
+ memo[:expression_attribute_names]["##{key}"] = key.to_s
51
+ memo[:expression_attribute_values][":#{key}"] = value
52
+ memo[:update_expression] << "##{key} = :#{key}"
53
+ end
54
+ update.merge(update_expression: "SET #{update[:update_expression].join(', ')}")
55
+ end
56
+ end
57
+ end
@@ -18,7 +18,7 @@
18
18
  module CodeBuildNotifier
19
19
  module Git
20
20
  def current_commit
21
- `git show -s --format='%h|%aN|%aE|%cE|%s'`.chomp.split('|')
21
+ `git show -s --format='%h|%aN|%aE|%cN|%cE|%s'`.chomp.split('|')
22
22
  end
23
23
  module_function :current_commit
24
24
  end
@@ -0,0 +1,125 @@
1
+ # codebuild-notifier
2
+ # Copyright © 2018 Adam Alboyadjian <adam@cassia.tech>
3
+ # Copyright © 2018 Vista Higher Learning, Inc.
4
+ #
5
+ # codebuild-notifier is free software: you can redistribute it
6
+ # and/or modify it under the terms of the GNU General Public
7
+ # License as published by the Free Software Foundation, either
8
+ # version 3 of the License, or (at your option) any later version.
9
+ #
10
+ # codebuild-notifier is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'digest'
19
+
20
+ module CodeBuildNotifier
21
+ class ProjectSummary < DynamoBase
22
+ # Creates entries in a partition key with hardcoded primary key.
23
+ # Within the partition key, there is one record for each github repo.
24
+ # The 'projects' field in that record is a Map data type, keyed off
25
+ # project code, containing the status of the last build for that code.
26
+ def update
27
+ return unless whitelisted_branch?
28
+
29
+ updates = project_summary_entry
30
+ yield updates if block_given?
31
+ update_item(updates)
32
+ end
33
+
34
+ private def whitelisted_branch?
35
+ config.whitelist_branches.include?(current_build.branch_name)
36
+ end
37
+
38
+ private def project_summary_entry
39
+ {
40
+ key: { source_id: source_id, version_key: version_key },
41
+ expression_attribute_names: attr_names,
42
+ expression_attribute_values: attr_values,
43
+ update_expression: update_expression
44
+ }
45
+ end
46
+
47
+ private def new_record?
48
+ return @new_record if defined?(@new_record)
49
+
50
+ item = dynamo_client.get_item(
51
+ key: {
52
+ 'source_id' => source_id, 'version_key' => version_key
53
+ },
54
+ table_name: dynamo_table
55
+ ).item
56
+ @new_record = item.nil?
57
+ end
58
+
59
+ private def source_id
60
+ 'project_summary'
61
+ end
62
+
63
+ # The repo url isn't a good format to use as a URL param.
64
+ private def version_key
65
+ Digest::MD5.hexdigest(current_build.git_repo_url)
66
+ end
67
+
68
+ private def attr_names
69
+ {
70
+ '#commit_hash' => 'commit_hash',
71
+ '#git_repo_url' => 'git_repo_url',
72
+ '#timestamp' => 'timestamp',
73
+ '#projects' => 'projects'
74
+ }.merge(project_code_attr_name)
75
+ end
76
+
77
+ # For an existing record, the project key already exists, so
78
+ # an attribute name is needed to be able to update the nested item
79
+ # path. For a new record, the project code is specified as the root
80
+ # key of the value assigned to the projects field.
81
+ private def project_code_attr_name
82
+ if new_record?
83
+ {}
84
+ else
85
+ { '#project_code' => current_build.project_code }
86
+ end
87
+ end
88
+
89
+ private def attr_values
90
+ {
91
+ ':build_status' => status_value,
92
+ ':commit_hash' => source_id,
93
+ ':git_repo_url' => current_build.git_repo_url,
94
+ ':timestamp' => current_build.start_time.to_i
95
+ }
96
+ end
97
+
98
+ private def status_map
99
+ {
100
+ 'build_id' => current_build.build_id,
101
+ 'status' => current_build.status,
102
+ 'timestamp' => current_build.start_time.to_i
103
+ }
104
+ end
105
+
106
+ # If a record already exists, we can address the nested item path for
107
+ # the current project directly and just store the updated status.
108
+ # Otherwise, we have to create a new map object in the projects field.
109
+ private def status_value
110
+ if new_record?
111
+ { current_build.project_code => status_map }
112
+ else
113
+ status_map
114
+ end
115
+ end
116
+
117
+ private def update_expression
118
+ projects_key = new_record? ? '#projects' : '#projects.#project_code'
119
+ 'SET #commit_hash = :commit_hash, ' \
120
+ '#timestamp = :timestamp, ' \
121
+ '#git_repo_url = :git_repo_url, ' \
122
+ "#{projects_key} = :build_status"
123
+ end
124
+ end
125
+ end
@@ -17,16 +17,14 @@
17
17
 
18
18
  module CodeBuildNotifier
19
19
  class SlackMessage
20
- attr_reader :author_email, :author_name, :build, :committer_email,
21
- :commit_message_subject, :config, :short_hash
20
+ attr_reader :build, :config
22
21
 
23
- delegate :source_ref, to: :build
22
+ delegate :author_email, :author_name, :committer_email,
23
+ :commit_message_subject, :short_hash, :source_ref, to: :build
24
24
 
25
25
  def initialize(build, config)
26
26
  @build = build
27
27
  @config = config
28
- @short_hash, @author_name, @author_email,
29
- @committer_email, @commit_message_subject = git_info
30
28
  end
31
29
 
32
30
  def payload
@@ -46,10 +44,6 @@ module CodeBuildNotifier
46
44
  !build.for_pr? && config.additional_channel
47
45
  end
48
46
 
49
- private def git_info
50
- Git.current_commit
51
- end
52
-
53
47
  private def slack_color
54
48
  {
55
49
  'FAILED' => 'danger',
@@ -16,5 +16,5 @@
16
16
  # along with codebuild-notifier. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  module CodeBuildNotifier
19
- VERSION = '0.3.2'.freeze
19
+ VERSION = '1.0.0'.freeze
20
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebuild-notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VHL Ops Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-27 00:00:00.000000000 Z
11
+ date: 2019-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -167,10 +167,13 @@ files:
167
167
  - bin/update-build-status
168
168
  - codebuild-notifier.gemspec
169
169
  - lib/codebuild-notifier.rb
170
+ - lib/codebuild-notifier/branch_entry.rb
170
171
  - lib/codebuild-notifier/build_history.rb
171
172
  - lib/codebuild-notifier/config.rb
172
173
  - lib/codebuild-notifier/current_build.rb
174
+ - lib/codebuild-notifier/dynamo_base.rb
173
175
  - lib/codebuild-notifier/git.rb
176
+ - lib/codebuild-notifier/project_summary.rb
174
177
  - lib/codebuild-notifier/slack_message.rb
175
178
  - lib/codebuild-notifier/slack_sender.rb
176
179
  - lib/codebuild-notifier/version.rb