-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.rb
197 lines (150 loc) · 3.87 KB
/
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/ruby
require 'rubygems'
require 'octokit'
class Repository
VALIDATION_ERROR = ['Action requires a GITHUB_REPOSITORY environment variable',
"with current repo path (f.e. 'owner/repo')"].join(' ').freeze
def initialize(source)
@source = source
end
def to_s
"#{owner}/#{repo}"
end
def validate!
return self if valid?
raise(VALIDATION_ERROR)
end
class << self
def from(source)
repository_cls(source).new(source).validate!
end
private
def repository_cls(source)
case source
when String then Env
when Hash then Payload
else Nil
end
end
end
class Env < Repository
def valid?
split_source.size >= 2
end
def owner
split_source.first
end
def repo
split_source.last
end
private
def split_source
@split_source ||= @source.split('/')
end
end
class Payload < Repository
def valid?
@source.key?('name') && @source.key?('owner') && @source['owner'].key?('login')
end
def owner
@source['owner']['login']
end
def repo
@source['name']
end
end
class Nil
def valid?
false
end
end
end
class Payload
EMPTY_JSON = '{}'.freeze
def [](key)
payload[key]
end
private
def payload
@payload ||= parse
end
def parse
return {} unless path
JSON.parse(file_contents)
end
def path
ENV['GITHUB_EVENT_PATH']
end
def file_contents
return File.read(path) if File.exist?(path)
puts("GITHUB_EVENT_PATH #{path} does not exist")
EMPTY_JSON
end
end
class Context
attr_reader :payload, :event_name, :sha, :ref, :workflow, :action, :actor
def initialize
@payload = Payload.new
@event_name = ENV['GITHUB_EVENT_NAME']
@sha = ENV['GITHUB_SHA']
@ref = ENV['GITHUB_REF']
@workflow = ENV['GITHUB_WORKFLOW']
@action = ENV['GITHUB_ACTION']
@actor = ENV['GITHUB_ACTOR']
end
def repository
@repository ||= Repository.from(ENV['GITHUB_REPOSITORY'] || @payload['repository'])
end
end
ACTION_NAME = 'duderman/gh-gem-tag-action@v1'
SHA = ENV['GITHUB_SHA']
TAG_TYPE = 'commit'.freeze
DEBUG_MSG_PREFIX = '::debug::'.freeze
def debug(msg)
log DEBUG_MSG_PREFIX + msg
end
def log(msg)
puts msg
end
class ArgIsMissing < StandardError
attr_reader :arg_name
def initialize(arg_name)
@arg_name = arg_name
end
def message
%Q('#{arg_name}' parameter is missing.
Set it as a step parameter. F.e:
- name: Tag it
uses: #{ACTION_NAME}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: v
)
end
end
def set_ouput(name, value)
puts "::set-output name=#{name}::#{value}"
end
gh_token = ARGV[0] || raise(ArgIsMissing, 'github_token')
tag_prefix = ARGV[1]
debug "Running action with: token = '#{gh_token}', " \
"tag_prefix: '#{tag_prefix}'"
current_dir = ENV.fetch('GITHUB_WORKSPACE', '.')
gemspec = Dir.entries(current_dir).detect { |file| File.extname(file) == '.gemspec' } || raise('.gemspec file not found')
spec = Gem::Specification::load(gemspec)
debug "Version from gemspec: #{spec.version}"
context = Context.new
octokit = Octokit::Client.new(access_token: gh_token)
commit = octokit.commit(context.repository.to_s, context.sha)
author = commit.commit.committer
debug "Commit author: #{author.name} <#{author.email}> @ #{author.date}"
tag_name = "#{tag_prefix}#{spec.version}"
debug "Creating a tag '#{tag_name}' for repo '#{context.repository}' at #{context.sha}"
tag = octokit.create_tag(context.repository.to_s, tag_name, '', context.sha, TAG_TYPE, author.name, author.email, author.date)
log "Created new tag: #{tag.tag}"
set_ouput('tag', tag.tag)
ref_name = "refs/tags/#{tag.tag}"
debug "Creating a ref '#{ref_name}' for sha #{tag.sha}"
ref = octokit.create_ref(context.repository.to_s, ref_name, tag.sha)
log "Ref #{ref.ref} created and available at #{ref.url}"
set_ouput('url', ref.url)