diff --git a/scripts/export_src.sh b/scripts/export_src.sh index 11a5290..0267c66 100755 --- a/scripts/export_src.sh +++ b/scripts/export_src.sh @@ -19,8 +19,9 @@ if [ -z "${GIT_BRANCH}" ]; then GIT_BRANCH="master" fi +LAST_COMMIT_DATE="" PROJECT_NAME=$1 -SRC_FOLDER_NAME="${PROJECT_NAME}-src-$(date +%F)" +SRC_FOLDER_NAME="${PROJECT_NAME}-src" SRC_DIR="./${SRC_FOLDER_NAME}" COMMAND_LINE_ARGUMENTS=$@ @@ -28,8 +29,19 @@ COMMAND_LINE_ARGUMENTS=$@ clone_platform() { PROJECT_NAME=$1 PLATFORM=$2 - - git clone --recurse-submodules -j8 "git@github.com:TouchInstinct/${PROJECT_NAME}-${PLATFORM}.git" --branch "${GIT_BRANCH}" + + if git clone --recurse-submodules -j8 "git@gitlab.ti:touchinstinct/${PROJECT_NAME}-${PLATFORM}.git" --branch "${GIT_BRANCH}"; then + cd ${PROJECT_NAME}-${PLATFORM} + + COMMIT_DATE=`git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d'` + if [[ $LAST_COMMIT_DATE < $COMMIT_DATE ]]; then + LAST_COMMIT_DATE="${COMMIT_DATE}" + fi + + cd .. + else + exit 1 + fi } mkdir -p "${SRC_DIR}" @@ -43,7 +55,11 @@ do fi done +if [ -z "${EXPORT_DATE}" ]; then + EXPORT_DATE="${LAST_COMMIT_DATE}" +fi + find . -name ".git*" -print0 | xargs -0 rm -rf -zip -r -q ${SRC_FOLDER_NAME}.zip . +zip -r -q "${SRC_FOLDER_NAME}-${EXPORT_DATE}".zip . open . diff --git a/xcode/bootstrap/Brewfile b/xcode/bootstrap/Brewfile new file mode 100644 index 0000000..396ea43 --- /dev/null +++ b/xcode/bootstrap/Brewfile @@ -0,0 +1,14 @@ +# Working environment +brew "rbenv" # ruby + bundler +brew "gettext" + +# Code, configs and project generation +brew "php" +brew "python" +brew "xcodegen" + +# code quality +brew "pmd" + +# CI badge +# brew "imagemagick" \ No newline at end of file diff --git a/xcode/bootstrap/Gemfile b/xcode/bootstrap/Gemfile new file mode 100644 index 0000000..8f79a29 --- /dev/null +++ b/xcode/bootstrap/Gemfile @@ -0,0 +1,9 @@ +source "https://rubygems.org" + +gem "cocoapods" +gem "fastlane" +gem 'mustache' # for config generator +gem 'xcode-install' + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) \ No newline at end of file diff --git a/xcode/bootstrap/Makefile b/xcode/bootstrap/Makefile new file mode 100644 index 0000000..7894911 --- /dev/null +++ b/xcode/bootstrap/Makefile @@ -0,0 +1,86 @@ +GREEN := $(shell tput -Txterm setaf 2) +YELLOW := $(shell tput -Txterm setaf 3) +WHITE := $(shell tput -Txterm setaf 7) +RESET := $(shell tput -Txterm sgr0) + +RUBY_VERSION="2.7.6" + +open_project=(open *.xcworkspace) +install_dev_certs=(bundle exec fastlane SyncCodeSigning type:development readonly:true) +install_pods=(bundle exec pod install || bundle exec pod install --repo-update) + +TARGET_MAX_CHAR_NUM=20 +## Show help +help: + @echo '' + @echo 'Использование:' + @echo ' ${YELLOW}make${RESET} ${GREEN}${RESET}' + @echo '' + @echo 'Команды:' + @awk '/^[a-zA-Z\-\_0-9]+:/ { \ + helpMessage = match(lastLine, /^## (.*)/); \ + if (helpMessage) { \ + helpCommand = substr($$1, 0, index($$1, ":")-1); \ + helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ + printf " ${YELLOW}%-$(TARGET_MAX_CHAR_NUM)s${RESET} ${GREEN}%s${RESET}\n", helpCommand, helpMessage; \ + } \ + } \ + { lastLine = $$0 }' $(MAKEFILE_LIST) + +## Инициализирует проект и устанавливает системные утилиты +init: + brew bundle + + eval "$(rbenv init -)" + + rbenv install -s ${RUBY_VERSION} + rbenv global ${RUBY_VERSION} + + if ! gem spec bundler > /dev/null 2>&1; then\ + echo "bundler gem is not installed!";\ + -sudo gem install bundler;\ + fi + + bundle install + + xcodegen + + $(call install_pods) + + bundle exec fastlane install_plugins + + $(call install_dev_certs) + + $(call open_project) + + git config --local core.hooksPath .githooks + +## Устанавливает поды +pod: + $(call install_pods) + +## Устанавливает сертификат и профили для запуска на девайсе +dev_certs: + $(call install_dev_certs) + +## Открывает папку для ручного редактирования сертификатов и профайлов +update_certs: + bundle exec fastlane ManuallyUpdateCodeSigning + +## Поднимает версию приложения (параметр "X.Y.Z") +bumpAppVersion: + ifeq ($(version),undefined) + @echo "Version parameter is missing (ex: x.y.z)" $(target) + else + bundle exec fastlane run increment_version_number version_number:$(version) + endif + +## Позволяет быстро открыть workspace проекта +start: + $(call open_project) + +## Очищает содержимое папки DerivedData +clean: + rm -rf ~/Library/Developer/Xcode/DerivedData/* + + diff --git a/xcode/bootstrap/setup.command b/xcode/bootstrap/setup.command new file mode 100755 index 0000000..0ae8983 --- /dev/null +++ b/xcode/bootstrap/setup.command @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_DIR="${DIR}/../../../" + +make init -C ${PROJECT_DIR} \ No newline at end of file diff --git a/xcode/commonFastfile b/xcode/commonFastfile index 0c00145..c196074 100644 --- a/xcode/commonFastfile +++ b/xcode/commonFastfile @@ -64,6 +64,7 @@ def upload_to_app_store_using_options(options) upload_to_app_store( username: options[:username] || options[:apple_id], api_key_path: options[:api_key_path], + api_key: options[:api_key], ipa: options[:ipa_path], force: true, # skip metainfo prompt skip_metadata: true, @@ -348,6 +349,7 @@ def sync_code_signing_using_options(options) app_identifier: options[:app_identifier], username: options[:username] || options[:apple_id], api_key_path: options[:api_key_path], + api_key: options[:api_key], team_id: options[:team_id], type: options[:type], readonly: options[:readonly].nil? ? true : options[:readonly], @@ -372,13 +374,33 @@ end def fill_up_options_using_configuration_type(options, configuration_type) configuration = get_configuration_for_type(configuration_type.type) - if configuration_type.is_app_store || configuration_type.is_development - api_key_path = "fastlane/#{configuration_type.prefix}_api_key.json" - else - api_key_path = nil - end + api_key_path = File.expand_path "../fastlane/#{configuration_type.prefix}_api_key.json" + is_api_key_file_exists = File.exists?(api_key_path) - default_options = {:api_key_path => api_key_path} + # default_options required to be empty due to the possibility of skipping the configuration type check below + + default_options = {} + + # Check whether configuration type is required to configure one of api key parameters or not + + if configuration_type.is_app_store || configuration_type.is_development + + # Check whether API key JSON file exists or not + + if is_api_key_file_exists + + # If exists then fill in all required information through api_key_path parameter + # and set a value to an options` parameter respectively + + default_options = {:api_key_path => api_key_path} + else + + # If doesn't exist then build api_key parameter through app_store_connect_api_key action + # and set a value to an options` parameter respectively also + + default_options = {:api_key => get_app_store_connect_api_key()} + end + end default_options .merge(configuration.to_options) @@ -386,6 +408,20 @@ def fill_up_options_using_configuration_type(options, configuration_type) .merge(options) end +def get_app_store_connect_api_key() + require 'json' + + api_key_parameters = JSON.parse(ENV['API_KEY_JSON']) + + return app_store_connect_api_key( + key_id: api_key_parameters['key_id'], + issuer_id: api_key_parameters['issuer_id'], + key_content: api_key_parameters['key'], + duration: api_key_parameters['duration'], + in_house: api_key_parameters['in_house'] + ) +end + def get_keychain_options(options) keychain_name = options[:keychain_name] keychain_password = options[:keychain_password]