пятница, 25 сентября 2015 г.

appveyor - travis-ci под windows

Я недавно делал обзор travis-ci и пожаловался на то, что там нет возможности прогонять тесты на windows. В комментариях ozkriff дал ссылку на appveyor.com, спасибо ему. Сервис как раз и специализируется на создании продукта для continuous integration под windows. У меня наконец дошли руки до того, что бы посмотреть на то, что он умеет, результаты далее.


Сервис похоже разрабатывался с оглядкой на travis-ci, поэтому сравнивать имеет смысл с ним же. Тут так же можно написать yml в котором перечислены шаги: инициализации системы, сборки продукта, прогона тестов, сборки артефактов, их деплоя и посылки нотификаций себе родимому. Порядок выполнения шагов можно посмотреть в документации. В качестве бонуса можно все шаги создать в визуальном web редакторе, который по функциональности позволяет делать всё то, что можно написать в конфиге. Обычно подобные редакторы гораздо более ограничены в возможностях. Вот пример одной из вкладок:

В принципе воспользовавшись последним, можно создать нужную конфигурацию почти не заглядывая в документацию, а потом преспокойно выгрузить appveyor.yml (их конфигурационный файл) и положить себе в репозиторий.

Из минусов - в отличии от travis-ci, там нет подготовленных виртуальных машины под разные языки, точнее они есть, но только для разных версий visual studio. Поэтому возникают некоторые сложности с подготовкой окружения, сами понимаете, что установить и настроить некоторые продукты под widows только при помощи powershell несколько затруднительно.

Сервис абсолютно бесплатен для open-source проектов, практически он не будет требовать деньги за работу с публичными репозиториями GitHub. Для таких проектов установлены некоторые ограничения в плане выделяемых тебе ресурсов сервера, но их вполне хватает. У меня сборка длиться ни чуть не медленнее чем аналогичная на travis-ci. А если учитывать, что я ещё сам настраиваю окружение, то и быстрее.

Предлагаю как в предыдущей статье попробовать что-то сделать на примере моего проекта rust-software-render на rust. Вот так выглядит мой appveyor.yml:
version: '{branch}.{build}'
skip_tags: true
clone_folder: c:\projects\git
environment:
  token:
    secure: /VxMVHbl3XzhHfFGCCu81O4JPgI42lbTT+n/opdJ7LW8XMsjgW3ztAPLI3u2TBro
  RUST_VERSION: rust-1.3.0
  SDL_VERSION: 2.0.3
  matrix:
  - TARGET1: x86_64
    TARGET2: x64
  - TARGET1: i686
    TARGET2: x86
install:
- ps: >-
    New-Item c:\projects\downloads -type directory

    New-Item c:\projects\cargo -type directory

    New-Item c:\projects\sdl -type directory

    New-Item c:\projects\git\artifacts -type directory


    cd c:\Python27\Scripts\

    ./easy_install pip

    ./pip install --disable-pip-version-check --pre github3.py

    cd c:\projects\downloads

    Start-FileDownload "https://static.rust-lang.org/dist/${env:RUST_VERSION}-${env:TARGET1}-pc-
                        windows-gnu.msi"

    Start-FileDownload "https://static.rust-lang.org/cargo-dist/cargo-nightly-${env:TARGET1}-pc-
                        windows-gnu.tar.gz"

    Start-FileDownload "https://www.libsdl.org/release/SDL2-${env:SDL_VERSION}-win32-${env:TARGET2}.zip"

    Start-FileDownload "https://www.libsdl.org/release/SDL2-devel-${env:SDL_VERSION}-mingw.tar.gz"

    If (${env:TARGET2} -eq "x86") {
    Start-FileDownload "http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/gcc-4.8.1-4/
                        gcc-core-4.8.1-4-mingw32-dll.tar.lzma"
    }


    Start-Process -FilePath msiexec -ArgumentList /i, ${env:RUST_VERSION}-${env:TARGET1}-pc-windows-gnu.msi,
                  INSTALLDIR="c:\projects\rust", /quiet -Wait

    7z x cargo-nightly-${env:TARGET1}-pc-windows-gnu.tar.gz

    7z x cargo-nightly-${env:TARGET1}-pc-windows-gnu.tar

    7z x SDL2-${env:SDL_VERSION}-win32-${env:TARGET2}.zip

    7z x SDL2-devel-${env:SDL_VERSION}-mingw.tar.gz

    7z x SDL2-devel-${env:SDL_VERSION}-mingw.tar

    If (${env:TARGET2} -eq "x86") {
    7z x gcc-core-4.8.1-4-mingw32-dll.tar.lzma
    }

    If (${env:TARGET2} -eq "x86") {
    7z x gcc-core-4.8.1-4-mingw32-dll.tar
    }


    Copy-Item cargo-nightly-${env:TARGET1}-pc-windows-gnu\cargo\* c:\projects\cargo\ -recurse

    Copy-Item SDL2-${env:SDL_VERSION}\${env:TARGET1}-w64-mingw32\lib\libSDL2.dll.a
              c:\projects\rust\bin\rustlib\${env:TARGET1}-pc-windows-gnu\lib\

    Copy-Item SDL2.dll c:\projects\sdl\

    Copy-Item SDL2.dll c:\projects\git\artifacts\

    If (${env:TARGET2} -eq "x86") {
    Copy-Item bin\libgcc_s_dw2-1.dll c:\projects\git\artifacts\
    }

    Copy-Item c:\projects\git\media c:\projects\git\artifacts\ -recurse


    $env:Path += ";c:\projects\rust\bin"

    $env:Path += ";c:\projects\cargo\bin"

    $env:Path += ";c:\projects\sdl"

    cd c:\projects\git


    rustc -V

    cargo -V
build_script:
- ps: >-
    cargo build --release -v

    Copy-Item target\release\rust-software-render.exe artifacts\
test_script:
- ps: cargo test -v
before_deploy:
- ps: python -c"from github3 import login;import os;map(lambda x:x.delete(),
      [it for it in login(token=os.environ['token']).repository('ReanGD','rust-software-render')
      .releases() if it.tag_name==os.environ['APPVEYOR_REPO_BRANCH']+'-'+os.environ['TARGET2']+
      '-win'])"
artifacts:
- path: artifacts
  name: artifacts
deploy:
- provider: GitHub
  tag: $(APPVEYOR_REPO_BRANCH)-$(TARGET2)-win
  release: $(APPVEYOR_REPO_BRANCH)-$(TARGET2)-win
  description: $(APPVEYOR_REPO_BRANCH)-$(TARGET2) for windows
  auth_token:
    secure: /VxMVHbl3XzhHfFGCCu81O4JPgI42lbTT+n/opdJ7LW8XMsjgW3ztAPLI3u2TBro
  artifact: artifacts.zip
notifications:
- provider: Email
  to:
  - reangd@yandex.ru
  on_build_success: false
  on_build_failure: true
  on_build_status_changed: false
В принципе тут должно быть почти всё понятно, пройдёмся по самый интересным местам:
  • В "environment\matrix" задана матрица из 2 наборов переменных окружения, это нужно для того, что бы appveyor на каждый push делал две сборки, в данном случае для x64 и x86 конфигураций. Ко всем установленным переменным окружения, наряду с предустановленными можно обращаться из любой секции конфига.
  • Секция "install" не представляет ничего интересного - скрипт на powershell который качает и ставит rust, cargo и необходимые библиотеки.
  • Секция build_script позволяет удобно настроить сборку visual studio проектов, но в данном случае я просто добавил скрипт, который собирает проект через cargo.
  • Секция test_script опять же заточена на специализированные фреймворки тестирования (в основном под C#), ну а нам приходиться довольствоваться скриптом на powershell.
  • Секция artifacts - тут все просто, можно задать либо целую директорию (обязательно относительно корня проекта), либо набор файлов, которые система положит в zip архив и в дальнейшем их можно будет либо просто скачать, либо использовать в шаге deploy.
  • Секция deploy предоставляет возможность деплоя в самые разные хранилища, среди самых интересных для меня можно выделить интеграцию с GitHub, позволяющую выкладывать релизы прямо рядом с репозиторием. Тут остановлюсь чуть подробнее, т.к. есть подводные камни. Во-первых обращение к хранилищу Github требует использования токена, задание которого в явном виде - очевидно не безопасно, поэтому они предоставляют возможность шифрования значений переменных и в примере значение "auth_token" у меня является как раз зашифрованным токеном. Ещё стоит обратить внимание на то, что сервис не умеет удалять старые release и если для указанного тега уже существует выложенный release, то сборка просто упадет с ошибкой. Что бы обойти эту проблему, я в секции "before_deploy" составил адский однострочник, который делает это самостоятельно. В остальном там всё понятно из документации.
  • C notifications тут и объяснять нечего и так всё понятно, только отмечу, что одним email там поддержка не ограничивается.
После сборки конечно же можно посмотреть полные логи того, что происходило на сервере. В качестве примера могу дать ссылку на мои. Все основные возможности я озвучил, за нюансами добро пожаловать в документацию.

В целом впечатления положительные, единственная трудность с которой я столкнулся - когда нет под рукой windows трудно писать powershell скрипты, но это конечно моя проблема, а не сервиса. Ещё хотелось бы отметить неплохую производительность, я ожидал худшего, боюсь только что это связано с низкой популярностью сервиса и как следствие с низкой нагрузкой. Так же есть опасения, что сервис может закрыться, поэтому я бы не стал завязываться на него в коммерческих проектах. Ну и традиционно - если позволяет время и есть ресурсы, для внутреннего потребления я бы всё же настроил Jenkins, который гибче и функциональнее.

8 комментариев:

  1. Ух и масштабный у тебя конфиг получился)

    Я себе такое впилил, попроще (только с mingw заморочки): https://github.com/ozkriff/zoc/blob/e766cd/appveyor.yml

    ОтветитьУдалить
    Ответы
    1. У меня дома винды нет, поэтому я это всё делал вслепую: добавляешь команду и прогоняешь тест на appveyor. В итоге наверное install секция немного не оптимальная получилась.

      А ты в свой конфиг добавь установку зависимых библиотек, сборку артифактов, заливку их на github и т.п. - посмотрим, какой у тебя получится в итоге )

      Удалить
    2. У меня тоже сейчас доступа к виндовой машине нет. Как раз потому и настроил appveyor, что бы виндовая версия совсем уж не "сгнила".

      Надо бы еще для андроида чего-то придумать, но пока не будет официальной бинарной версии стандартной библиотеки под android-arm, то тут все печально. Не заставлять же трэвис собирать всю стандартную библиотеку)

      Зависимые библиотеки у меня и сейчас ставятся, как раз из-за сишного stb-truetype (вроде, единственный кусок не на ржавчине) и пришлось с mingw мучаться. Вот бы и от него избавиться, вроде ребята из piston какой-то порт пилят - https://github.com/PistonDevelopers/truetype .

      А сборку и заливку артефактов - это да, пока делать не тянет)

      Удалить
    3. cargo, кстати, вроде теперь сразу с ржавчиной ставится

      Удалить
    4. >> А сборку и заливку артефактов - это да, пока делать не тянет)

      Делай делай, что бы можно было в один клик скачать и потестировать, мало кто заморочится компиляцией из исходников

      Удалить
    5. Я точно скоро выложу собранный вручную .apk, потому что его собрать - это вообще адово сложно. С андроидом вообще как-то все всегда сложно :( .

      А автоматизировать сборку виндовых бинарей, еще и с учетом отсутствия у меня сейчас доступа к виндовой машине для их проверки, все-таки кажется преждевременным. Все равно на данный момент zoc если и интересен кому, то только увлекающимся ржавчиной, а им собрать из исходников не должно быть сложно)

      Удалить
    6. Извиняюсь, запутался в блогспотовских комментариях. Оффтоп, но тебе вообще удобны местные комментарии? Я бы с большим удовольствием в disqus'е комменты оставлял)

      Удалить
    7. Нет не удобны, но disqus когда я последний раз смотрел на него - сказал что он не поддерживает больше синхронизацию с блогером, может с тех пор что-то поменялось, нужно посмотреть

      Удалить