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 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
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](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,5 @@
1
+ module Fastlane
2
+ module KmmPusher
3
+ VERSION = "1.0.0"
4
+ end
5
+ 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: []