fastlane-plugin-stream_actions 0.4.3 → 0.4.5
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 588bc089b57e2d637ed87e062d4f70b47b9ed434a902331ade91e775b97c251d
|
|
4
|
+
data.tar.gz: '09dd367927a51c2976dc9e2bc2a52827b78ff26b9c6e37bacb6bbd66d1ffc23b'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d125f60bb7937c1825928b57c77b02eb49fae737636792b252fb257e882817be3b978003ef2d9aea4b4a0a8c7b57c2062b0b1f94a76bb75c103c0cc0b6a3f60a
|
|
7
|
+
data.tar.gz: 07e0d6184d4e3b363fbb0f4cabbff98dd681e96a96b89f7184f2b5bf5cd9d4a746a0eba382181c1866aa4443f55e3bf3c4cafa01aef3d0df3c3bf90e4251444a
|
|
@@ -14,15 +14,106 @@ module Fastlane
|
|
|
14
14
|
return true
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
changed_files
|
|
18
|
-
|
|
17
|
+
if self.touches_sources?(changed_files, params[:sources])
|
|
18
|
+
UI.important("Check is required: true")
|
|
19
|
+
return true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
required_checks = params[:required_checks].to_a
|
|
23
|
+
if required_checks.empty?
|
|
24
|
+
UI.important("Check is required: false")
|
|
25
|
+
return false
|
|
19
26
|
end
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
# The current push does not touch :sources. It is only safe to skip if :sources were already
|
|
29
|
+
# verified, i.e. all required checks passed on some commit that has the current :sources tree.
|
|
30
|
+
is_check_required = self.required_due_to_history(params, required_checks)
|
|
22
31
|
UI.important("Check is required: #{is_check_required}")
|
|
23
32
|
is_check_required
|
|
24
33
|
end
|
|
25
34
|
|
|
35
|
+
def self.touches_sources?(files, sources)
|
|
36
|
+
files.any? { |path| sources.any? { |required| path.start_with?(required) } }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Walks the PR commits from newest to oldest. Every commit newer than the last :sources change
|
|
40
|
+
# has the current :sources tree, so a passing run on any of them means :sources were verified.
|
|
41
|
+
# The walk stops at the commit that changed :sources, since older commits have different sources.
|
|
42
|
+
def self.required_due_to_history(params, required_checks)
|
|
43
|
+
repo = (params[:github_repository] || ENV['GITHUB_REPOSITORY']).to_s
|
|
44
|
+
if repo.empty?
|
|
45
|
+
UI.important("No repository provided; cannot verify previous runs, running check")
|
|
46
|
+
return true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
shas = self.pr_commit_shas(params[:github_pr_num])
|
|
50
|
+
if shas.empty?
|
|
51
|
+
UI.important("Could not list PR commits; running check")
|
|
52
|
+
return true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
shas.each do |sha|
|
|
56
|
+
short = sha[0, 7]
|
|
57
|
+
if self.required_checks_passed?(repo, sha, required_checks)
|
|
58
|
+
UI.message("Commit #{short} passed required checks for the current sources; safe to skip")
|
|
59
|
+
return false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
next unless self.touches_sources?(self.commit_files(repo, sha), params[:sources])
|
|
63
|
+
|
|
64
|
+
UI.important("Last sources commit #{short} was not verified by a passing run; running check")
|
|
65
|
+
return true
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
UI.message("No commit in this PR changed sources; nothing to test")
|
|
69
|
+
false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# PR commits, newest first (gh returns them oldest first).
|
|
73
|
+
def self.pr_commit_shas(pr_num)
|
|
74
|
+
self.gh_path_lines(Actions.sh("gh pr view #{pr_num} --json commits -q '.commits[].oid'")).reverse
|
|
75
|
+
rescue StandardError
|
|
76
|
+
[]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Files changed by a single commit (relative to its first parent).
|
|
80
|
+
def self.commit_files(repo, sha)
|
|
81
|
+
self.gh_path_lines(Actions.sh("gh api repos/#{repo}/commits/#{sha} --paginate -q '.files[].filename'"))
|
|
82
|
+
rescue StandardError
|
|
83
|
+
[]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# True only if every required check has its latest run concluded as 'success' on the commit.
|
|
87
|
+
def self.required_checks_passed?(repo, sha, required_checks)
|
|
88
|
+
out = Actions.sh(
|
|
89
|
+
"gh api \"repos/#{repo}/commits/#{sha}/check-runs?per_page=100\" --paginate " \
|
|
90
|
+
"-H \"Accept: application/vnd.github.v3+json\" " \
|
|
91
|
+
"-q '.check_runs[] | \"\\(.name)\\t\\(.conclusion)\\t\\(.completed_at)\"'"
|
|
92
|
+
)
|
|
93
|
+
latest = self.latest_conclusions(out)
|
|
94
|
+
required_checks.all? { |name| latest[name] == 'success' }
|
|
95
|
+
rescue StandardError
|
|
96
|
+
false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Reduces "name\tconclusion\tcompleted_at" lines to the latest conclusion per check name,
|
|
100
|
+
# so re-runs of the same check supersede earlier attempts.
|
|
101
|
+
def self.latest_conclusions(output)
|
|
102
|
+
latest = {}
|
|
103
|
+
seen_at = {}
|
|
104
|
+
output.to_s.split("\n", -1).each do |line|
|
|
105
|
+
name, conclusion, completed_at = line.split("\t", -1)
|
|
106
|
+
next if name.nil? || name.strip.empty?
|
|
107
|
+
|
|
108
|
+
completed_at = completed_at.to_s
|
|
109
|
+
next if seen_at.key?(name) && completed_at < seen_at[name]
|
|
110
|
+
|
|
111
|
+
seen_at[name] = completed_at
|
|
112
|
+
latest[name] = conclusion.to_s
|
|
113
|
+
end
|
|
114
|
+
latest
|
|
115
|
+
end
|
|
116
|
+
|
|
26
117
|
# For pull_request: use full PR for `opened` (etc.); for `synchronize` pass
|
|
27
118
|
# github_event_before/after (e.g. github.event.before/after) to scope to this push.
|
|
28
119
|
def self.changed_file_paths(params)
|
|
@@ -83,6 +174,16 @@ module Fastlane
|
|
|
83
174
|
description: 'GitHub PR number',
|
|
84
175
|
optional: true
|
|
85
176
|
),
|
|
177
|
+
FastlaneCore::ConfigItem.new(
|
|
178
|
+
key: :required_checks,
|
|
179
|
+
description: 'Names of GitHub check runs that must have concluded as success on the last commit ' \
|
|
180
|
+
'that changed :sources for the check to be skipped when the current push does not ' \
|
|
181
|
+
'touch :sources. When empty, the check is skipped as soon as the current push does ' \
|
|
182
|
+
'not touch :sources',
|
|
183
|
+
is_string: false,
|
|
184
|
+
optional: true,
|
|
185
|
+
default_value: []
|
|
186
|
+
),
|
|
86
187
|
FastlaneCore::ConfigItem.new(
|
|
87
188
|
key: :force_check,
|
|
88
189
|
description: 'GitHub PR number',
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fastlane-plugin-stream_actions
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GetStream
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: xctest_list
|