fastlane-plugin-kmm_pusher 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 +7 -0
- data/LICENSE +21 -0
- data/README.md +17 -0
- data/lib/fastlane/plugin/kmm_pusher/actions/kmm_pusher_action.rb +105 -0
- data/lib/fastlane/plugin/kmm_pusher/helper/kmm_pusher_helper.rb +208 -0
- data/lib/fastlane/plugin/kmm_pusher/version.rb +5 -0
- data/lib/fastlane/plugin/kmm_pusher.rb +16 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cc0dc39bb6d7296db350e7e9c7e34ba124dfeeea36e447392524bd6ebab7c9ad
|
4
|
+
data.tar.gz: 9cff20f4ad7cb9480541516c72704f2c97a986626565f3a25db2b8378e243809
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d6579a39529f30de6625e51bb5a0e1965f1722ca64c010c48e82bc85490666de10289e0d6783509dd4be2911242b25fe52c1b2119fa9c7339d36ef571a87145d
|
7
|
+
data.tar.gz: 62ab3f6d33b9d4217b0f26aeeff5e0685a839980cf24d1adcf3168a317acee9b6bb1033a58a2b5d410bc7605fbd475801d057f2614da44ce25e33d30008ef385
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 Yazan Tarifi <yazantarifi989@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
## Fastlane Plugin: KMM Pusher 🚀
|
2
|
+
|
3
|
+
A Fastlane plugin to streamline the build, distribution, and notification process for Kotlin Multiplatform (KMM) projects. This plugin integrates seamlessly with Fastlane to automate your KMM workflows and keep your team informed via Slack.
|
4
|
+
|
5
|
+
## Features ✨
|
6
|
+
1. Build KMM Projects: Automate the build process for Kotlin Multiplatform projects.
|
7
|
+
2. Upload Files to Slack: Easily upload build artifacts (.aar, .zip, .xcframework) to Slack channels.
|
8
|
+
3. Notify Teams: Send build status updates and notifications to Slack channels.
|
9
|
+
4. Customizable: Configure the plugin to suit your project's needs.
|
10
|
+
|
11
|
+
[](https://rubygems.org/gems/fastlane-plugin-kmm_pusher)
|
12
|
+
|
13
|
+
Commands
|
14
|
+
```
|
15
|
+
gem build fastlane-plugin-kmm_pusher.gemspec
|
16
|
+
gem install ./fastlane-plugin-kmm_pusher-0.0.14.gem
|
17
|
+
```
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require_relative '../helper/kmm_pusher_helper'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
class KmmPusherAction < Action
|
7
|
+
def self.run(params)
|
8
|
+
UI.message("Fastlane Kotlin Multiplatform Pusher Started ...")
|
9
|
+
|
10
|
+
is_xc_framework_enabled = params[:is_xc_framework_enabled]
|
11
|
+
service_type = params[:service_type]
|
12
|
+
project_name = params[:project_name]
|
13
|
+
is_commit_enabled = params[:is_commit_enabled]
|
14
|
+
commit_message = params[:commit_message]
|
15
|
+
slack_channel = params[:slack_channel]
|
16
|
+
slack_app_token = params[:slack_app_token]
|
17
|
+
|
18
|
+
Helper::KmmPusherHelper.start_plugin(
|
19
|
+
project_name,
|
20
|
+
service_type,
|
21
|
+
is_xc_framework_enabled,
|
22
|
+
is_commit_enabled,
|
23
|
+
commit_message,
|
24
|
+
slack_channel,
|
25
|
+
slack_app_token
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.description
|
30
|
+
"Kotlin Multiplatform Mobile Plugin to Collect Android and IOS Builds to Push them on Slack"
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.authors
|
34
|
+
["Yazan Tarifi"]
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.return_value
|
38
|
+
# If your method provides a return value, you can describe here what it does
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.details
|
42
|
+
"Build Kotlin Multiplatform Mobile Library Projects and Generate Builds to Push them on Slack Channels to be able to Track All KMM Library Builds"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.available_options
|
46
|
+
[
|
47
|
+
FastlaneCore::ConfigItem.new(
|
48
|
+
key: :project_name,
|
49
|
+
env_name: "KMM_PUSHER_PROJECT_NAME",
|
50
|
+
description: "Module Name of the Library that you Generate Builds on",
|
51
|
+
optional: false,
|
52
|
+
type: String
|
53
|
+
),
|
54
|
+
FastlaneCore::ConfigItem.new(
|
55
|
+
key: :is_xc_framework_enabled,
|
56
|
+
env_name: "KMM_PUSHER_XC_TRACK_ENABLED",
|
57
|
+
description: "Decide which Builds Enabled for XCFramework or Normal Framework",
|
58
|
+
optional: false,
|
59
|
+
type: Boolean
|
60
|
+
),
|
61
|
+
FastlaneCore::ConfigItem.new(
|
62
|
+
key: :service_type,
|
63
|
+
env_name: "KMM_PUSHER_SERVICE_TYPE",
|
64
|
+
description: "Service Type to Push the Builds on (slack, discord, telegram)",
|
65
|
+
optional: false,
|
66
|
+
type: String
|
67
|
+
),
|
68
|
+
FastlaneCore::ConfigItem.new(
|
69
|
+
key: :is_commit_enabled,
|
70
|
+
env_name: "KMM_PUSHER_COMMIT_ENABLED",
|
71
|
+
description: "Boolean Value to Decide if the Commit after Build enabled or Not",
|
72
|
+
optional: true,
|
73
|
+
type: Boolean
|
74
|
+
),
|
75
|
+
FastlaneCore::ConfigItem.new(
|
76
|
+
key: :commit_message,
|
77
|
+
env_name: "KMM_PUSHER_COMMIT_MESSAGE",
|
78
|
+
description: "Send the Commit Message when Push the Build Results",
|
79
|
+
optional: true,
|
80
|
+
type: String
|
81
|
+
),
|
82
|
+
FastlaneCore::ConfigItem.new(
|
83
|
+
key: :slack_channel,
|
84
|
+
env_name: "KMM_PUSHER_SLACK_CHANNEL",
|
85
|
+
description: "Channel name that KMM Pusher gonna Push the Builds on",
|
86
|
+
optional: true,
|
87
|
+
type: String
|
88
|
+
),
|
89
|
+
FastlaneCore::ConfigItem.new(
|
90
|
+
key: :slack_app_token,
|
91
|
+
env_name: "KMM_PUSHER_APP_TOKEN",
|
92
|
+
description: "Application Bot Name that KMM Pusher Push the Builds on",
|
93
|
+
optional: true,
|
94
|
+
type: String
|
95
|
+
),
|
96
|
+
]
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.is_supported?(platform)
|
100
|
+
[:ios, :android].include?(platform)
|
101
|
+
true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
require 'zip'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
|
6
|
+
|
7
|
+
module Helper
|
8
|
+
class KmmPusherHelper
|
9
|
+
def self.start_plugin(
|
10
|
+
project_name,
|
11
|
+
service_type,
|
12
|
+
is_xc_framework_enabled,
|
13
|
+
is_commit_enabled,
|
14
|
+
commit_message,
|
15
|
+
slack_channel,
|
16
|
+
slack_app_token
|
17
|
+
)
|
18
|
+
|
19
|
+
# Pre Check Plugin Params before Start the Plugin
|
20
|
+
raise PluginMissingParamsException, print_error_message("project_name is required in configuration!") if project_name.nil? || project_name.empty?
|
21
|
+
raise PluginMissingParamsException, print_error_message("service_type is required in configuration!") if service_type.nil? || service_type.empty?
|
22
|
+
|
23
|
+
# Pre Check on Slack Configurations if Service Type is Slack
|
24
|
+
if service_type == "slack"
|
25
|
+
raise PluginMissingParamsException, print_error_message("slack_channel is required in configuration!") if slack_channel.nil? || slack_channel.empty?
|
26
|
+
raise PluginMissingParamsException, print_error_message("slack_app_token is required in configuration!") if slack_app_token.nil? || slack_app_token.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Print Plugin Params Start
|
30
|
+
print_log_message("KMM Pusher Started with Project #{project_name} and Service Type #{service_type}")
|
31
|
+
|
32
|
+
# 1. Remove Prev Build for Android and IOS
|
33
|
+
delete_prev_builds(project_name)
|
34
|
+
|
35
|
+
# 2. Start Building the Library By Project Module
|
36
|
+
build_library_module(project_name, is_xc_framework_enabled)
|
37
|
+
|
38
|
+
# 3. Find Build Paths
|
39
|
+
move_builds_to_root_path(project_name)
|
40
|
+
|
41
|
+
# 4. Compress Files to Zip Files
|
42
|
+
if is_xc_framework_enabled
|
43
|
+
compress_files(project_name, "xcframework")
|
44
|
+
else
|
45
|
+
compress_files(project_name, "framework")
|
46
|
+
end
|
47
|
+
|
48
|
+
# 5. Check if the Git Commits Enabled after Build Push the Builds to Repository
|
49
|
+
if is_commit_enabled
|
50
|
+
push_build(commit_message)
|
51
|
+
end
|
52
|
+
|
53
|
+
# 6. Push the Builds to Service
|
54
|
+
if service_type == "slack"
|
55
|
+
push_slack_build(slack_channel, project_name, is_xc_framework_enabled, slack_app_token)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.push_slack_build(slack_channel, project_name, is_xc_framework_enabled, token)
|
61
|
+
if is_xc_framework_enabled
|
62
|
+
upload_file_to_slack(
|
63
|
+
"#{get_current_working_directory}/#{project_name}.xcframework.zip",
|
64
|
+
slack_channel,
|
65
|
+
"A new Build Pushed for IOS Client with XCFramework",
|
66
|
+
token
|
67
|
+
)
|
68
|
+
else
|
69
|
+
upload_file_to_slack(
|
70
|
+
"#{get_current_working_directory}/#{project_name}.framework.zip",
|
71
|
+
slack_channel,
|
72
|
+
"A new Build Pushed for IOS Client with Framework",
|
73
|
+
token
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
upload_file_to_slack(
|
78
|
+
"#{get_current_working_directory}/#{project_name}-debug.aar",
|
79
|
+
slack_channel,
|
80
|
+
"A new Build Pushed for Android Client with Framework",
|
81
|
+
token
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.get_current_working_directory
|
86
|
+
Dir.pwd
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.upload_file_to_slack(file_path, channel, initial_comment = nil, slack_token)
|
90
|
+
Actions.sh("node pusher.js #{file_path} \"#{channel}\" \"#{initial_comment}\" #{slack_token}")
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.compress_files(project_name, extention)
|
94
|
+
# Define the file to compress
|
95
|
+
file_to_compress = "#{project_name}.#{extention}"
|
96
|
+
zip_file = "#{file_to_compress}.zip"
|
97
|
+
|
98
|
+
# Create the ZIP file
|
99
|
+
Zip::File.open(zip_file, Zip::File::CREATE) do |zip|
|
100
|
+
if File.directory?(file_to_compress)
|
101
|
+
# Add all files in the directory recursively
|
102
|
+
Dir["#{file_to_compress}/**/**"].each do |file|
|
103
|
+
zip.add(file.sub("#{file_to_compress}/", ""), file)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
# Add a single file
|
107
|
+
zip.add(File.basename(file_to_compress), file_to_compress)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
print_log_message("Successfully created #{zip_file}")
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.push_build(commit_message)
|
115
|
+
Actions.sh("git add .")
|
116
|
+
Actions.sh("git commit -m \"#{commit_message}\" ")
|
117
|
+
|
118
|
+
current_branch = get_git_reference
|
119
|
+
Actions.sh("git push origin #{current_branch}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.get_git_reference
|
123
|
+
# Try to get the first tag name
|
124
|
+
first_tag = `git describe --tags --abbrev=0 2>&1`.strip
|
125
|
+
|
126
|
+
if $?.success?
|
127
|
+
first_tag
|
128
|
+
else
|
129
|
+
# Fall back to the current branch name
|
130
|
+
current_branch = `git rev-parse --abbrev-ref HEAD 2>&1`.strip
|
131
|
+
current_branch
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.move_builds_to_root_path(project_name)
|
136
|
+
print_log_message("Start Moving Builds from Build Folder to Root Folder")
|
137
|
+
|
138
|
+
directory = Actions.sh("pwd").delete(" \t\r\n")
|
139
|
+
iosSourceDirectory = directory + "/#{project_name}/build/XCFrameworks/release/#{project_name}.xcframework"
|
140
|
+
androidBuildDirectory = directory + "/#{project_name}/build/outputs/aar/#{project_name}-debug.aar"
|
141
|
+
|
142
|
+
print_log_message("Current Working Directory : #{directory}")
|
143
|
+
print_log_message("IOS Working Directory : #{iosSourceDirectory}")
|
144
|
+
print_log_message("Android Working Directory : #{androidBuildDirectory}")
|
145
|
+
|
146
|
+
Actions.sh("mv " + iosSourceDirectory + " " + directory + "/#{project_name}.xcframework")
|
147
|
+
Actions.sh("mv " + androidBuildDirectory + " " + directory + "/#{project_name}-debug.aar")
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.build_library_module(project_name, is_xc_framework_enabled)
|
151
|
+
Actions.sh("./gradlew #{project_name}:clean")
|
152
|
+
Actions.sh("./gradlew #{project_name}:assemble")
|
153
|
+
if is_xc_framework_enabled
|
154
|
+
Actions.sh("./gradlew #{project_name}:assembleXCFramework")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.delete_prev_builds(project_name)
|
159
|
+
begin
|
160
|
+
Actions.sh("rm ./#{project_name}-debug.aar")
|
161
|
+
rescue Exception
|
162
|
+
# Ignored if Not Exists
|
163
|
+
end
|
164
|
+
|
165
|
+
begin
|
166
|
+
Actions.sh("rm -rf ./#{project_name}.framework")
|
167
|
+
rescue Exception
|
168
|
+
# Ignored if Not Exists
|
169
|
+
end
|
170
|
+
|
171
|
+
begin
|
172
|
+
Actions.sh("rm -rf ./#{project_name}.xcframework")
|
173
|
+
rescue Exception
|
174
|
+
# Ignored if Not Exists
|
175
|
+
end
|
176
|
+
|
177
|
+
begin
|
178
|
+
Actions.sh("rm -rf ./#{project_name}.framework.zip")
|
179
|
+
rescue Exception
|
180
|
+
# Ignored if Not Exists
|
181
|
+
end
|
182
|
+
|
183
|
+
begin
|
184
|
+
Actions.sh("rm -rf ./#{project_name}.xcframework.zip")
|
185
|
+
rescue Exception
|
186
|
+
# Ignored if Not Exists
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.print_log_message(message)
|
191
|
+
puts " ---------------------------------------- "
|
192
|
+
puts " -------------- #{message} -------------- "
|
193
|
+
puts " ---------------------------------------- "
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.print_error_message(message)
|
197
|
+
"\e[31m ------ [#{message}] ------ \e[0m"
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.show_message
|
201
|
+
UI.message("Kotlin Pusher Plugin Started Message")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class PluginMissingParamsException < StandardError
|
208
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/kmm_pusher/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module KmmPusher
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::KmmPusher.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-kmm_pusher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yazan Tarifi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: yazantarifi989@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- LICENSE
|
20
|
+
- README.md
|
21
|
+
- lib/fastlane/plugin/kmm_pusher.rb
|
22
|
+
- lib/fastlane/plugin/kmm_pusher/actions/kmm_pusher_action.rb
|
23
|
+
- lib/fastlane/plugin/kmm_pusher/helper/kmm_pusher_helper.rb
|
24
|
+
- lib/fastlane/plugin/kmm_pusher/version.rb
|
25
|
+
homepage: https://github.com/Yazan98/KMM-Pusher
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubygems_version: 3.5.18
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Kotlin Multiplatform Mobile Plugin to Collect Android and IOS Builds to Push
|
48
|
+
them on Slack
|
49
|
+
test_files: []
|