Github actions


Привет, Хабр. Это статья о том как автоматизировать ваш проект с помощью github actions.
Автоматизация будет делиться на:


  • CI — над каждым коммитом будут проведены тесты
  • Publish — при релизе публикуем версию в npm

CI


В нашем репозитории (о том как мы до этого дошли можно почитать здесь) для есть следующие скрипты:


  • npm run build — Построение
  • npm test — Тесты
  • npm run codestyle — Проверка стиля кода
    Мы будем запускать билд и тесты на 3 версиях node (8, 10, 12) и проверку стиля кода одновременно
    За данный workflow будет отвечать файл .github/workflows/CI.yml:

name: Node CI

on: push

jobs:
  buildAndTest:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [8.x, 10.x, 12.x]

    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Install, build, test
      run: |
        npm install
        npm run build
        npm test
      env:
        CI: true

  checkCodestyle:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: '8.x'
    - name: Install and check codestyle
      run: |
        npm install
        npm run codestyle
      env:
        CI: true

Разберём его содержимое
name: Node CI строка содержащая название workflow
on: push будем запускать workflow на пуше
jobs: это задание которое нужно выполнить


Задание buildAndTest:


buildAndTest: # Название
    runs-on: ubuntu-latest # ОС на которой запускаемся

    strategy: # Это стратегия запусков
      matrix: # Запускать это задание с разными параметрами
        node-version: [8.x, 10.x, 12.x] # Версии ноды

    steps: # Шаги выполнения
    - uses: actions/checkout@v1 
    - name: Use Node.js ${{ matrix.node-version }} # Установим ноду
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}

    - name: Install, build, test # Выполняем необходимые команды
      run: |
        npm install
        npm run build
        npm test
      env: # В окружении устанавливаем CI в истину 
        CI: true

Можно заметить интересную конструкцию ${{ something }} это обращение к контексту данного запускаю Там где something какое-то выражение, в нашем случае matrix.node-version, то есть мы получаем значение в объекте matrix с названием node-version. В matrix храниться значение переменных заданных в текущем запуске, в нашем случае при трёх запусках там будут лежать значения 8.x, 10.x, 12.x


Задание checkCodestyle


checkCodestyle:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: '8.x'
    - name: Install and check codestyle
      run: |
        npm install
        npm run codestyle
      env:
        CI: true

Ну тут всё аналогично первому


Publish


name: Publish # Название workflow
on: 
  release # Условие запуска (по релизу)

jobs: # Задания
  test: # Тестирование, тут всё просто
    runs-on: ubuntu-latest 
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 12
      - run: npm ci
      - run: npm run build
      - run: npm test
      - run: npm run codestyle

  publish: # Опубликовать 
    needs: test # Запускать только если тест прошёл успешно
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 12 # Запускать на 12 ноде
          registry-url: https://registry.npmjs.org/
      - run: npm run build # Выполняем билд

      - name: Publish beta # Публикуем бету
        if: github.event.prerelease == true # Выполнить этот шаг только если это пререлиз
        run: npm publish --tag beta
        env:
          NODE_AUTH_TOKEN: ${{secrets.npm}}

      - name: Publish stable # Публикуем стабильную версию
        if: github.event.prerelease == false # Только если не пререлиз
        run: npm publish --tag beta
        env:
          NODE_AUTH_TOKEN: ${{secrets.npm}}

      - name: Build and Deploy dосs # Запускаем доку
        uses: JamesIves/github-pages-deploy-action@master
        if: github.event.prerelease == false
        env:
          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
          BRANCH: gh-pages
          FOLDER: docs
          BUILD_SCRIPT: npm install && npm run typedoc ## Скрипт для построения доки

Из интересного здесь ${{ secrets.SOMETHING }} это обращение к элементу SOMETHING в объекте SOMETHING
Здесь я обращаюсь к двум секретным значениям:


  • npm — NPM токен
  • ACCESS_TOKEN — Доступ к gh-pages(токен github)

Secrets можно создать в настройках проекта


И не менее интересные строчки это


if: github.event.prerelease == true
if: github.event.prerelease == false

If позволяют сказать github какие шаги выполнять, а какие нет.
Для этого мы берём значение github.event.prerelease, github.event содержит json объект получаемый в webhook release, и если оно true то публикуем бету,
если false то публикуем стабильную и доку


Вот так просто можно всё автоматизировать с github actions


Ссылки


Финальный репозиторий
Библиотека на npm
Пример документации


Документация по github actions
Работа с контекстом
Работа с секретными значениями
Описание webhook release

Комментарии (4)


  1. onegreyonewhite
    25.09.2019 06:57

    Что вы думаете о github actions

    IMHO. После нескольких лет использования Gitlab CI вообще выглядит неплохо, но до оценки "Прекрасно" не дотягивает:


    • Workflows разделены на файлы, но выглядит немного запутано.
    • Лично мне не хватает stages со всей той логикой. Хотя структура Workflows тоже хороша.
    • Нельзя загружать шаблоны из файлов по url или из других директорий, хотя возможно это и плюс, чтобы не плодить бардак в структуре и не получать неожиданностей.
    • Как насчёт сервисов? Что нужно сделать, чтобы выполнить:
      docker build ...

    Но в целом выглядит привлекательно.


    1. maximmasterr Автор
      25.09.2019 07:21

      О поддержке сервисов (nginx, redis): можно почитать здесь


      А чтобы построить контейнер, вместо npm build используйте docker build


      1. onegreyonewhite
        25.09.2019 12:05

        А чтобы построить контейнер, вместо npm build используйте docker build

        Вопрос был не в команде, а в сервисе докера.
        Спасибо что кинули ссылку, а то при беглом осмотре не увидел.


    1. Amet13
      26.09.2019 23:14

      Что нужно сделать, чтобы выполнить:
      docker build ...

      Пока только так, к сожалению: habr.com/en/post/468345
      Но это дело времени, сервис-то пока в бете, наверняка скоро напишет Action для докера.