Ваш новый разработчик только что закончил подписывать трудовой договор и с горящими глазами готов закрывать по 15 задач в день. На его пути стоит лишь одно препятствие — новый ноутбук, который пока что не настроен должным образом. Чаще всего процесс настройки окружения описывается в документе, который выдается новому разработчику. Мы не сильно далеко ушли и тоже составили такой список.
-
Установка Xcode
-
Настройка локального git репозитория
-
Настройка окружения
-
Настройка проекта
-
Ознакомление с документацией
-
Настройка таск-трекера (Jira/Youtrack)
Чтобы не тратить драгоценное время разработчика на ручную настройку нового ноутбука, мы автоматизировали 3 и 4 пункты, т.к. они являются самыми трудозатратными.
Итак, давайте сперва рассмотрим настройку окружения.
Настройка окружения
В нашем случае настройка окружения состоит из нескольких пунктов:
1. Установка brew зависимостей
2. Установка mint зависимостей
3. Установка и настройка ruby
4. Установка и настройка python
Чтобы упростить настройку вышеперечисленных пунктов, мы воспользовались Ansible. Он помогает решать множество задач, таких как управление сетями, операционными системами, развертка серверной инфраструктуры, – мы же ограничились простой настройкой локальной машины через playbooks.
Но и тут мы не остановились и решили еще больше облегчить жизнь нового разработчика и написали скрипт, который устанавливает ansible и производит настройку вышеперечисленных пунктов.
В конечном итоге скрипт получился вот таким:
#!/usr/bin/env bash curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && sudo python get-pip.py sudo pip install ansible cd $(dirname $0) && ansible-playbook main.yml
Тут происходит следующее:
-
Установка менеджера пакетов pip
-
Установка Ansible
-
Запуск наших задач из
main.yml
Осталось разобраться, что находится в main.yml. А там всего лишь
- hosts: localhost roles: - common_setup
Здесь hosts отвечает за те машины, на которых мы хотим запустить наши задачи, в нашем случае это локальная машина, а roles содержит информацию о том, какие задачи нужно выполнить, переменные и метаинформацию.
roles ожидает, что файлы будут находиться в определенных папках, в нашем случае иерархия выглядит вот так
Каждая папка (meta, tasks и vars) должна содержать файл main.yml.
Все команды можно уместить в главном main.yml, но подход через roles обеспечивает большую читаемость и модульность.
Больше всего нас интересует папка tasks, в которой собраны задачи, выполняющие настройку. Рассмотрим структуру задачи, которая выполняет установку и настройку Ruby с помощью rvm.
--- - name: Check if RVM already installed stat: path=~/.rvm register: rvmdir changedwhen: false - name: Install RVM for a user command: bash -c "\curl -sSL https://get.rvm.io | bash -s -- --ignore-dotfiles" when: rvmdir.stat.exists == False - name: Add RVM to profile command: bash -c "~/.rvm/bin/rvm get stable --auto-dotfiles" when: rvmdir.stat.exists == False - name: Add RVM to zshrc command: bash -c "echo '\n[ -s ${HOME}/.rvm/scripts/rvm ] && source ${HOME}/.rvm/scripts/rvm' >> ~/.zshrc" when: rvmdir.stat.exists == False - name: Install {{ rubyversion }} command: bash -c "~/.rvm/bin/rvm install {{ rubyversion }}" when: rvmdir.stat.exists == False - name: Set Ruby Default command: bash -c "~/.rvm/bin/rvm --default use {{ rubyversion }}" when: rvmdir.stat.exists == False - name: Install Ruby Gems required for iOS app developement gem: name={{ item.name }} version={{ item.version }} state={{ if item.version is defined nil else latest }} withitems: "{{ rubygems_packages_to_install }}" when: rvmdir.stat.exists == False
-
Проверяем, установлен ли rvm.
name— название задачиstat— путь до rvmregisterсохраняет переменную для последующего использованияchanged_whenпереопределяет поведение смены состояния машины после исполненияМы точно знаем, что после исполнения этой задачи состояние не изменится, поэтому просто ставим false. Более подробно использование этой команды описано здесь.
-
Устанавливаем rvm.
name— название задачиcommand— команда для выполненияwhen— условие для выполненияУсловием для выполнения здесь является отсутствие установленного ранее rvm, мы можем узнать это из сохраненной на предыдущем шаге переменной
rvmdir. -
Настраиваем rvm. Параметры аналогичны.
-
Добавляем строки в .zshrc конфиг. На MacOS Catalina этот шаг обязателен, так как zsh теперь используется по умолчанию.
-
Устанавливаем нужную нам для разработки версию Ruby. Тут параметры тоже аналогичны, единственным отличием будет использование нашей переменной из папки vars. Объявлена она в
main.ymlследующим образом:rubyversion: ruby-2.6.5 -
Назначаем свежеустановленную версию Ruby версией по умолчанию
-
Устанавливаем нужные гемы, в нашем случае это просто bundler. Тут также используется переменная из папки vars, объявленная таким образом:
rubygems_packages_to_install:- name: bundlerversion:2.1.4
На этом настройка окружения закончена, можем переходить к настройке самого проекта.
Настройка проекта
Под настройкой проекта мы подразумеваем полную установку всех зависимостей и других необходимых вещей для успешного билда.
Скрипт для настройки проекта выглядит следующим образом:
#!/usr/bin/ruby require 'FileUtils' require 'colorize' RESOURCES_DIRECTORY = './Scripts/Resources'.freeze XCODE_DIRECTORY = '~/Library/Developer/Xcode'.freeze def setup_git_hooks puts "Setting up git hooks".blue.bold git_hooks_path = '.git/hooks' FileUtils.mkdir_p(git_hooks_path) Dir["#{RESOURCES_DIRECTORY}/Git hooks/*"].each do |file| FileUtils.cp_r(file, "#{git_hooks_path}/#{File.basename(file)}") end end def setup_file_templates puts "\nSetting up file templates".blue.bold file_templates_path = File.expand_path("#{XCODE_DIRECTORY}/Templates/File Templates/Tests") FileUtils.mkdir_p(file_templates_path) Dir["#{RESOURCES_DIRECTORY}/Templates/*.xctemplate"].each do |file| FileUtils.cp_r(file, "#{file_templates_path}/#{File.basename(file)}") end end def setup_xcode_snippets puts "\nSetting up xcode snippets".blue.bold need_to_reboot_xcode = false code_snippets_path = File.expand_path("#{XCODE_DIRECTORY}/UserData/CodeSnippets") FileUtils.mkdir_p(code_snippets_path) Dir["#{RESOURCES_DIRECTORY}/Snippets/*.codesnippet"].each { |file| path = "#{code_snippets_path}/#{File.basename(file)}" next if File.file?(path) need_to_reboot_xcode = true FileUtils.cp_r(file, path) } return unless need_to_reboot_xcode puts 'Quiting Xcode'.blue system('killall Xcode') end def setup_gems puts "\nSetting up gems".blue.bold system('bundle install') end def setup_mocks puts "\nSetting up mocks".blue.bold system('cd $(pwd) && swiftymocky generate') end def setup_projects puts "\nSetting up projects".blue.bold system('bundle exec rake update_projects') end # Steps Dir.chdir("#{File.expand_path(File.dirname(__FILE__))}/..") setup_git_hooks setup_file_templates setup_xcode_snippets setup_gems setup_mocks setup_projects
Что тут вообще происходит:
-
Настройка гит-хуков. В нашем случае к коммиту всегда прибавляется номер задачи, который берется из названия ветки.
-
Установка темплейтов для генерации модулей.
-
Установка полезных сниппетов.
-
Установка гемов.
-
Генерация моков.
-
Настройка проекта.
Чуть подробнее, пожалуй, стоит остановиться на последнем шаге. В нем мы подтягиваем и кэшируем все нужные Carthage зависимости и генерируем файлы проектов с помощью XcodeGen.
Заключение
Настройка проекта и установка всех зависимостей занимает в нашем случае около 1 часа, который новый разработчик может потратить на чтение других вводных документов и общение с наставником. Благодаря этим скриптам мы точно знаем, что окружения всех наших разработчиков синхронизированы, тем самым мы можем избежать многих непонятных ошибок.
В итоге мы сэкономили время нового разработчика при онбординге и позволили ему быстрее приступить к задачам. Более того, этими же скриптами мы настраиваем билд-агенты, получая от скриптов двойную пользу.
ссылка на оригинал статьи https://habr.com/ru/company/vivid_money/blog/539898/
Добавить комментарий