fastlane-plugin-push_cert_alert 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b314ae55ef7470ee477d2d7b46f23f4ece80e477632575809330e94bb2f5cb7c
4
+ data.tar.gz: 4cd8dd84c0656ae00a04a8b6bf9bb89353204bb6782387e0b13170e949fc5198
5
+ SHA512:
6
+ metadata.gz: 83e3299951c1e85e36dc018e838f7da6d29a52a9e52fdd7e2109c3cee3c542a992a5c8a474e2e2a9447d03a45f9243d2a8bb1af83b514efef3da8e3c72b49312
7
+ data.tar.gz: 5fd618d89f6f2ebdf60a8bda7415af363b6a3d54d0c555fc28e659fa99816b9b1a65f8f185a052e9b0d668c8a8b0c97d9d3c7636c952d713ee52e2ed49f11f03
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Nico Richard <nicorichard@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,99 @@
1
+ # Push Cert Alert - Fastlane Plugin
2
+
3
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-push_cert_alert)
4
+
5
+ Fastlane's [PEM](https://docs.fastlane.tools/actions/pem/) tool provides amazing capabilities for generating new push certificates when the old one will expire.
6
+
7
+ But what if you just want to just check the expiration date without making modifications? Or alert your team on Slack when the date is approaching?
8
+
9
+ ## Getting Started
10
+
11
+ This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-push_cert_alert`, add it to your project by running:
12
+
13
+ ```bash
14
+ fastlane add_plugin push_cert_alert
15
+ ```
16
+
17
+ ## About push_cert_alert
18
+
19
+ Generate alerts for when a push certificate will expire soon, or has expired already.
20
+
21
+ ## Usage
22
+
23
+ > If you already use get_push_certificate (pem) and slack actions somewhere in your lanes then you are already configured.\
24
+ > Run `bundle exec fastlane action push_cert_alert` for more information.
25
+
26
+ Simply add `check_push_certificate` to some lane:
27
+
28
+ ```ruby
29
+ lane :test do
30
+ check_push_certificate
31
+ end
32
+ ```
33
+
34
+ And you will receive a Slack alert when your cert has expired (or expires soon):
35
+
36
+ > An APNS push certificate expires in 30 days
37
+ >
38
+ > **Lane:** test\
39
+ > **Result:** Error\
40
+ > **App Identifier:** com.company.name\
41
+ > **Type:** production\
42
+ > **Expires at:** 1955-11-05 11:11:11 UTC\
43
+ > **Name:** Apple Push Services
44
+
45
+ You can also add custom callbacks for the events if desired:
46
+
47
+ ```ruby
48
+ check_push_certificate(
49
+ active_days_limit: 60, # Default is 30
50
+ skip_slack: true, # Defaults to true
51
+ expires_soon: proc do |cert, days|
52
+ puts "#{days} days until #{cert.name} expires. Perhaps you should run `get_push_certificate` soon to upgrade your push services."
53
+ end,
54
+ expired: proc do
55
+ puts "🚨 DANGER - Our push cert is expired (or missing)!"
56
+ end
57
+ )
58
+ ```
59
+
60
+ ## Integration
61
+
62
+ Integrate this lane with your other lanes and/or CI to be made aware early of any upcoming push certificate expiration.
63
+
64
+ ### Circle CI
65
+
66
+ Example Circle CI job which could be run with your daily builds
67
+
68
+ ```yaml
69
+
70
+ jobs:
71
+ push_cert_alert:
72
+ executor: my_executor
73
+ steps:
74
+ - checkout
75
+ - restore_cache
76
+ - install_bundles
77
+ - run: bundle exec fastlane YOUR LANE
78
+
79
+ ```
80
+
81
+ ## Example
82
+
83
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
84
+
85
+ ## Issues and Feedback
86
+
87
+ For any other issues and feedback about this plugin, please submit it to this repository.
88
+
89
+ ## Troubleshooting
90
+
91
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
92
+
93
+ ## Using _fastlane_ Plugins
94
+
95
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
96
+
97
+ ## About _fastlane_
98
+
99
+ _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
@@ -0,0 +1,159 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/login_helper'
3
+ require_relative '../helper/certificate_helper'
4
+ require_relative '../helper/slack_helper'
5
+
6
+ module Fastlane
7
+ module Actions
8
+ class CheckPushCertificateAction < Action
9
+ def self.run(params)
10
+ Helper::Login.login(params)
11
+
12
+ UI.message("Attempting to fetch existing an existing push certificate.")
13
+
14
+ existing_certificate = Helper::Certificate.existing_certificate(params)
15
+ remaining_days = existing_certificate ? Helper::Certificate.remaining_days(existing_certificate) : 0
16
+
17
+ if existing_certificate and remaining_days > 0
18
+ UI.message("The push notification profile for '#{existing_certificate.owner_name}' is valid for #{remaining_days.round} days")
19
+
20
+ if remaining_days < params[:active_days_limit]
21
+ UI.message("The push notification profile is valid for less than the limit of #{params[:active_days_limit]} days")
22
+
23
+ params[:expires_soon].call(existing_certificate, remaining_days) if params[:expires_soon]
24
+
25
+ Helper::Slack.slack(
26
+ message: "An APNS push certificate expires in #{remaining_days} days",
27
+ certificate: existing_certificate,
28
+ params: params
29
+ ) if not params[:skip_slack]
30
+ end
31
+ else
32
+ if existing_certificate
33
+ UI.message("The push notification profile has expired")
34
+ else
35
+ UI.message("A push notification profile cannot be found")
36
+ end
37
+
38
+ params[:expired].call() if params[:expired]
39
+
40
+ Helper::PushCertAlertSlackHelper.slack(
41
+ message: "An APNS push certificate has expired or cannot be found",
42
+ params: params
43
+ ) if not params[:skip_slack]
44
+ end
45
+ end
46
+
47
+ def self.description
48
+ "Easily create alerts for your APNS push certificate expiration"
49
+ end
50
+
51
+ def self.authors
52
+ ["Nico Richard"]
53
+ end
54
+
55
+ def self.available_options
56
+ user = CredentialsManager::AppfileConfig.try_fetch_value(:apple_dev_portal_id)
57
+ user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
58
+
59
+ [
60
+ FastlaneCore::ConfigItem.new(key: :expires_soon,
61
+ description: "Block that is called if the profile expires in less than the `active_days_limit`. Called with `certificate, days_remaining`",
62
+ optional: true,
63
+ type: Proc),
64
+ FastlaneCore::ConfigItem.new(key: :expired,
65
+ description: "Block that is called if the profile is expired. Called with empty params",
66
+ optional: true,
67
+ type: Proc),
68
+ FastlaneCore::ConfigItem.new(key: :active_days_limit,
69
+ env_name: "PEM_ACTIVE_DAYS_LIMIT",
70
+ description: "If the current certificate is active for less than this number of days, generate a new one",
71
+ default_value: 30,
72
+ is_string: false,
73
+ type: Integer,
74
+ verify_block: proc do |value|
75
+ UI.user_error!("Value of active_days_limit must be a positive integer or left blank") unless value.kind_of?(Integer) && value > 0
76
+ end),
77
+ # Spaceship Certificate Fetching
78
+ FastlaneCore::ConfigItem.new(key: :development,
79
+ env_name: "PEM_DEVELOPMENT",
80
+ description: "Renew the development push certificate instead of the production one",
81
+ is_string: false,
82
+ default_value: false),
83
+ FastlaneCore::ConfigItem.new(key: :website_push,
84
+ env_name: "PEM_WEBSITE_PUSH",
85
+ description: "Create a Website Push certificate",
86
+ is_string: false,
87
+ conflicting_options: [:development],
88
+ default_value: false),
89
+ FastlaneCore::ConfigItem.new(key: :app_identifier,
90
+ short_option: "-a",
91
+ env_name: "PEM_APP_IDENTIFIER",
92
+ description: "The bundle identifier of your app",
93
+ code_gen_sensitive: true,
94
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier),
95
+ default_value_dynamic: true),
96
+ FastlaneCore::ConfigItem.new(key: :username,
97
+ short_option: "-u",
98
+ env_name: "PEM_USERNAME",
99
+ description: "Your Apple ID Username",
100
+ default_value: user,
101
+ default_value_dynamic: true),
102
+ FastlaneCore::ConfigItem.new(key: :team_id,
103
+ short_option: "-b",
104
+ env_name: "PEM_TEAM_ID",
105
+ code_gen_sensitive: true,
106
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:team_id),
107
+ default_value_dynamic: true,
108
+ description: "The ID of your Developer Portal team if you're in multiple teams",
109
+ optional: true,
110
+ verify_block: proc do |value|
111
+ ENV["FASTLANE_TEAM_ID"] = value.to_s
112
+ end),
113
+ # Slack
114
+ FastlaneCore::ConfigItem.new(key: :skip_slack,
115
+ description: "Skip sending an alert to Slack",
116
+ optional: true,
117
+ type: Boolean,
118
+ default_value: false),
119
+ FastlaneCore::ConfigItem.new(key: :slack_url,
120
+ short_option: "-i",
121
+ env_name: "SLACK_URL",
122
+ sensitive: true,
123
+ description: "Create an Incoming WebHook for your Slack group to post results there",
124
+ optional: true,
125
+ verify_block: proc do |value|
126
+ if !value.to_s.empty? && !value.start_with?("https://")
127
+ UI.user_error!("Invalid URL, must start with https://")
128
+ end
129
+ end),
130
+ FastlaneCore::ConfigItem.new(key: :slack_channel,
131
+ short_option: "-e",
132
+ env_name: "SCAN_SLACK_CHANNEL",
133
+ description: "#channel or @username",
134
+ optional: true)
135
+ ]
136
+ end
137
+
138
+ def self.is_supported?(platform)
139
+ platform == :ios
140
+ end
141
+
142
+ def self.example_code
143
+ [
144
+ <<-CODE
145
+ check_push_certificate(
146
+ active_days_limit: 60,
147
+ expires_soon: proc do |cert, days|
148
+ puts "#{days} days to live!"
149
+ end,
150
+ expired: proc do
151
+ puts "UH OH!!! Our push cert may be expired!"
152
+ end
153
+ )
154
+ CODE
155
+ ]
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,41 @@
1
+ require 'spaceship'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class Certificate
6
+ def self.certificate(params)
7
+ if params[:development]
8
+ Spaceship.certificate.development_push
9
+ elsif params[:website_push]
10
+ Spaceship.certificate.website_push
11
+ else
12
+ Spaceship.certificate.production_push
13
+ end
14
+ end
15
+
16
+ def self.certificate_type(params)
17
+ if params[:development]
18
+ 'development'
19
+ elsif params[:website_push]
20
+ 'website'
21
+ else
22
+ 'production'
23
+ end
24
+ end
25
+
26
+ def self.certificate_sorted(params)
27
+ certificate(params).all.sort { |x, y| y.expires <=> x.expires }
28
+ end
29
+
30
+ def self.existing_certificate(params)
31
+ certificate_sorted(params).detect do |c|
32
+ c.owner_name == params[:app_identifier]
33
+ end
34
+ end
35
+
36
+ def self.remaining_days(certificate)
37
+ ((certificate.expires - Time.now) / 60 / 60 / 24).round(2)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ require 'spaceship'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class Login
6
+ def self.login(params)
7
+ UI.message("Starting login with user '#{params[:username]}'")
8
+ Spaceship.login(params[:username], nil)
9
+ Spaceship.client.select_team
10
+ UI.message("Successfully logged in")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,51 @@
1
+ require 'fastlane/action'
2
+ require 'fastlane/actions/slack'
3
+ require 'fastlane_core/configuration/configuration'
4
+
5
+ module Fastlane
6
+ module Helper
7
+ class Slack
8
+ def self.slack(message: "APNS Push Cert Alert", certificate: nil, params: {})
9
+ fields = [
10
+ {
11
+ title: "App Identifier",
12
+ value: params[:app_identifier],
13
+ short: true
14
+ },
15
+ {
16
+ title: "Type",
17
+ value: Helper::Certificate.certificate_type(params),
18
+ short: true
19
+ }
20
+ ]
21
+
22
+ if certificate
23
+ fields << {
24
+ title: "Expires at",
25
+ value: certificate.expires,
26
+ short: true
27
+ }
28
+
29
+ fields << {
30
+ title: "Name",
31
+ value: certificate.name,
32
+ short: true
33
+ }
34
+ end
35
+
36
+ options = FastlaneCore::Configuration.create(Fastlane::Actions::SlackAction.available_options, {
37
+ message: message,
38
+ channel: params[:slack_channel],
39
+ slack_url: params[:slack_url],
40
+ success: false,
41
+ payload: {},
42
+ attachment_properties: {
43
+ fields: fields
44
+ }
45
+ })
46
+
47
+ Fastlane::Actions::SlackAction.run(options)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module PushCertAlert
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/push_cert_alert/version'
2
+
3
+ module Fastlane
4
+ module PushCertAlert
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::PushCertAlert.all_classes.each do |current|
15
+ require current
16
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-push_cert_alert
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nico Richard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fastlane
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.197.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.197.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec_junit_formatter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 1.12.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 1.12.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-performance
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-require_tools
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description:
154
+ email: nicorichard@gmail.com
155
+ executables: []
156
+ extensions: []
157
+ extra_rdoc_files: []
158
+ files:
159
+ - LICENSE
160
+ - README.md
161
+ - lib/fastlane/plugin/push_cert_alert.rb
162
+ - lib/fastlane/plugin/push_cert_alert/actions/check_push_certificate_action.rb
163
+ - lib/fastlane/plugin/push_cert_alert/helper/certificate_helper.rb
164
+ - lib/fastlane/plugin/push_cert_alert/helper/login_helper.rb
165
+ - lib/fastlane/plugin/push_cert_alert/helper/slack_helper.rb
166
+ - lib/fastlane/plugin/push_cert_alert/version.rb
167
+ homepage: https://github.com/CityTransit/fastlane-plugin-push_cert_alert
168
+ licenses:
169
+ - MIT
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '2.5'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubygems_version: 3.0.3
187
+ signing_key:
188
+ specification_version: 4
189
+ summary: Generate alerts for when your APNS push certificate expires or will expire
190
+ soon
191
+ test_files: []