feat: implement deployement pipeline (#2)
This commit is contained in:
parent
ee58f96126
commit
155d048c18
@ -7,7 +7,7 @@ module Fastlane
|
||||
def self.run(params)
|
||||
# Check parameters
|
||||
unless Helper::AndroidCdHelper.is_set(params[:beta_type])
|
||||
UI.error("Parameters beta_type cannot be null")
|
||||
UI.error("❌ Parameters beta_type cannot be null")
|
||||
puts("Error on beta type parameter")
|
||||
end
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
# Ruby CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
|
||||
#
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/ruby:2.5
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "Gemfile" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v1-dependencies-
|
||||
|
||||
- run:
|
||||
name: install dependencies
|
||||
command: bundle check || bundle install --jobs=4 --retry=3 --path vendor/bundle
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ./vendor
|
||||
key: v1-dependencies-{{ checksum "Gemfile" }}
|
||||
|
||||
# run tests!
|
||||
- run:
|
||||
name: run tests
|
||||
command: bundle exec rake
|
||||
|
||||
# collect reports
|
||||
- store_test_results:
|
||||
path: ~/repo/test-results
|
||||
- store_artifacts:
|
||||
path: ~/repo/test-results
|
||||
destination: test-results
|
@ -2,5 +2,7 @@ source('https://rubygems.org')
|
||||
|
||||
gemspec
|
||||
|
||||
gem 'json'
|
||||
|
||||
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
|
||||
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
||||
|
@ -0,0 +1,116 @@
|
||||
require 'fastlane/action'
|
||||
require_relative '../helper/ios_cd_helper'
|
||||
|
||||
module Fastlane
|
||||
module Actions
|
||||
class BuildAndDeploy < Action
|
||||
def self.run(params)
|
||||
# Check parameters
|
||||
unless Helper::IosCdHelper.is_set(params[:beta_type])
|
||||
UI.error("❌ Parameters beta_type cannot be null")
|
||||
puts("Error on beta type parameter")
|
||||
end
|
||||
|
||||
UI.message("⌛️ Building and deploying to Store in #{params[:beta_type]}..")
|
||||
|
||||
# Decrypt the keys archive and Extract the keys archive
|
||||
Helper::IosCdHelper.decrypt_ios_keys('.')
|
||||
|
||||
# Retrieve credentials
|
||||
creds = Helper::IosCdHelper.parseIosCredentials
|
||||
|
||||
UI.message(creds.to_s)
|
||||
|
||||
# Ensure temporary keychain exists
|
||||
Fastlane::Actions.ensure_temp_keychain(creds['temp_keychain_user'], creds['temp_keychain_password'])
|
||||
|
||||
# Obtain App Store Connect API key
|
||||
api_key = Fastlane::Actions.app_store_connect_api_key(
|
||||
key_id: creds['apple_key_id'],
|
||||
issuer_id: creds['apple_issuer_id'],
|
||||
key_content: creds['apple_key_content'],
|
||||
duration: 1200,
|
||||
in_house: false
|
||||
)
|
||||
|
||||
# Increment build number for latest TestFlight build
|
||||
Fastlane::Actions.increment_build_number({
|
||||
build_number: Fastlane::Actions.latest_testflight_build_number + 1,
|
||||
xcodeproj: "Runner.xcodeproj"
|
||||
})
|
||||
|
||||
# Install Cocoapods
|
||||
Fastlane::Actions.cocoapods(
|
||||
clean_install: true
|
||||
)
|
||||
|
||||
# Set up code signing using match
|
||||
# Configures and runs `match` which manages code signing certificates and provisioning profiles for the project.
|
||||
# The function takes the app's bundle identifier, an authorization token for the project's Git repository, and the name and password for a temporary keychain used to store the signing certificate.
|
||||
# It uses the App Store Connect API key to access the App Store and increment the build number.
|
||||
# It then runs `gym` to build and sign the app using the selected provisioning profile, and finally, uses `pilot` to upload the app to TestFlight for beta testing.
|
||||
Fastlane::Actions.match(
|
||||
type: 'appstore',
|
||||
app_identifier: creds['app_identifier_extensions'],
|
||||
git_basic_authorization: Base64.strict_encode64(ENV["GIT_AUTHORIZATION"]),
|
||||
keychain_name: creds['temp_keychain_user'],
|
||||
keychain_password: creds['temp_keychain_password'],
|
||||
api_key: api_key
|
||||
)
|
||||
|
||||
# Build and export app using Gym
|
||||
# Builds and packages an iOS app or framework for distribution to the App Store, TestFlight, or Enterprise distribution.
|
||||
Fastlane::Actions.gym(
|
||||
configuration: "Release",
|
||||
workspace: "Runner.xcworkspace",
|
||||
scheme: "your_schema",
|
||||
export_method: "app-store",
|
||||
export_options: {
|
||||
provisioningProfiles: creds['provisioning_profiles']
|
||||
}
|
||||
)
|
||||
|
||||
# Upload build to App Store Connect using Pilot
|
||||
Fastlane::Actions.pilot(
|
||||
apple_id: creds['developer_app_id'].to_s,
|
||||
app_identifier: creds['developer_app_identifier'].to_s,
|
||||
skip_waiting_for_build_processing: true,
|
||||
skip_submission: true,
|
||||
distribute_external: false,
|
||||
notify_external_testers: false,
|
||||
ipa: "./Runner.ipa"
|
||||
)
|
||||
|
||||
Fastlane::Actions.delete_temp_keychain
|
||||
end
|
||||
|
||||
def self.description
|
||||
"Testflight and AppStore deployment plugin for Fastlane, simplifying the build and deployment porcess to internal, external, and production channels, and promoting builds for testing."
|
||||
end
|
||||
|
||||
def self.authors
|
||||
["SAS Wyatt Studio"]
|
||||
end
|
||||
|
||||
def self.return_value
|
||||
end
|
||||
|
||||
def self.details
|
||||
"The Fastlane Testflight / Appstore deloyment action streamlines the build and deployment to internal, external and production channels. Allow you to promote builds on testflight beta tests."
|
||||
end
|
||||
|
||||
def self.available_options
|
||||
[
|
||||
FastlaneCore::ConfigItem.new(key: :beta_type,
|
||||
env_name: "IOS_CD_TEST_TYPE",
|
||||
optional: false,
|
||||
description: "Type of test (internal, external, production)")
|
||||
]
|
||||
end
|
||||
|
||||
def self.is_supported?(platform)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,47 +0,0 @@
|
||||
require 'fastlane/action'
|
||||
require_relative '../helper/ios_cd_helper'
|
||||
|
||||
module Fastlane
|
||||
module Actions
|
||||
class IosCdAction < Action
|
||||
def self.run(params)
|
||||
UI.message("The ios_cd plugin is working!")
|
||||
end
|
||||
|
||||
def self.description
|
||||
"Testflight and AppStore deployment plugin for Fastlane, simplifying the build and deployment porcess to internal, external, and production channels, and promoting builds for testing."
|
||||
end
|
||||
|
||||
def self.authors
|
||||
["Malo Léon"]
|
||||
end
|
||||
|
||||
def self.return_value
|
||||
# If your method provides a return value, you can describe here what it does
|
||||
end
|
||||
|
||||
def self.details
|
||||
# Optional:
|
||||
"The Fastlane Testflight / Appstore deloyment action streamlines the build and deployment to internal, external and production channels. Allow you to promote builds on testflight beta tests."
|
||||
end
|
||||
|
||||
def self.available_options
|
||||
[
|
||||
# FastlaneCore::ConfigItem.new(key: :your_option,
|
||||
# env_name: "IOS_CD_YOUR_OPTION",
|
||||
# description: "A description of your option",
|
||||
# optional: false,
|
||||
# type: String)
|
||||
]
|
||||
end
|
||||
|
||||
def self.is_supported?(platform)
|
||||
# Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
|
||||
# See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
|
||||
#
|
||||
# [:ios, :mac, :android].include?(platform)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,15 +1,71 @@
|
||||
require 'fastlane/action'
|
||||
require 'json'
|
||||
require 'fastlane_core/ui/ui'
|
||||
|
||||
module Fastlane
|
||||
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
||||
|
||||
module Helper
|
||||
class IosCdHelper
|
||||
# class methods that you define here become available in your action
|
||||
# as `Helper::IosCdHelper.your_method`
|
||||
#
|
||||
def self.show_message
|
||||
UI.message("Hello from the ios_cd plugin helper!")
|
||||
# Define method to delete temporary keychain
|
||||
def delete_temp_keychain(name)
|
||||
if File.exist?(File.expand_path("~/Library/Keychains/#{name}-db"))
|
||||
Fastlane::Actions.delete_keychain(
|
||||
name: name
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Define method to create temporary keychain
|
||||
def create_temp_keychain(name, password)
|
||||
Fastlane::Actions.create_keychain(
|
||||
name: name,
|
||||
password: password,
|
||||
unlock: false,
|
||||
timeout: 0
|
||||
)
|
||||
end
|
||||
|
||||
# Define method to ensure that temporary keychain exists
|
||||
def ensure_temp_keychain(name, password)
|
||||
delete_temp_keychain(name)
|
||||
create_temp_keychain(name, password)
|
||||
end
|
||||
|
||||
# Check if a parameter is set or not
|
||||
def self.is_set(variable)
|
||||
str_variable = variable
|
||||
str_variable = variable.strip if variable.class.to_s == "String"
|
||||
variable && !(str_variable.nil? || str_variable.empty?)
|
||||
end
|
||||
|
||||
# Decrypts ios credentials
|
||||
def self.decrypt_ios_keys(ios_directory)
|
||||
# Define the GPG command with options
|
||||
gpg_command = "gpg --quiet --batch --yes --decrypt --passphrase=#{ENV['IOS_KEYS_SECRET_PASSPHRASE']} \
|
||||
--output #{ios_directory}/ios_keys.zip #{ios_directory}/ios_keys.zip.gpg"
|
||||
|
||||
# Execute the GPG command using system
|
||||
system(gpg_command)
|
||||
|
||||
# Check if the command executed successfully
|
||||
if $?.success?
|
||||
|
||||
# Move the extracted files to the current directory
|
||||
`jar xvf #{ios_directory} && mv #{ios_directory}/ios_keys/* #{ios_directory}`
|
||||
else
|
||||
puts("Erreur lors de la décompression du fichier GPG")
|
||||
end
|
||||
end
|
||||
|
||||
# Parse credential file
|
||||
def parseIosCredentials(ios_directory)
|
||||
if File.exists?("#{ios_directory}/ios_crendentials.json")
|
||||
# Read file and decrypt it
|
||||
file = File.read("#{ios_directory}/ios_crendentials.json")
|
||||
JSON.parse(file)
|
||||
|
||||
else
|
||||
UI.error("❌ Ios credentials doesn't exist")
|
||||
puts("json file doesn't exist")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,9 +1,9 @@
|
||||
describe Fastlane::Actions::IosCdAction do
|
||||
describe Fastlane::Actions::BuildAndDeploy do
|
||||
describe '#run' do
|
||||
it 'prints a message' do
|
||||
expect(Fastlane::UI).to receive(:message).with("The ios_cd plugin is working!")
|
||||
|
||||
Fastlane::Actions::IosCdAction.run(nil)
|
||||
Fastlane::Actions::BuildAndDeploy.run(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user