Рубрики
Uncategorized

Как настроить динамический трубопровод CI/CD с помощью GitHub

Создание единого трубопровода для вас вытащите запросы и слияния. Tagged с DevOps, CICD, GitHub.

Следуйте за мной в Твиттере в @Tim_deschryver | Подписаться на Информационный бюллетень | Первоначально опубликовано на Timdeschryver.dev Анкет

Прочитайте версию TLDR на timdeschryver.dev

Когда GitHub выпустил Действия GitHub Я переместил большинство своих трубопроводов CI/CD, чтобы использовать рабочий процесс GitHub. В каждом проекте было два рабочего процесса, один рабочий процесс, который запускался по запросам на притяжение, и второй рабочий процесс, который был вызван, когда кто -то подтолкнул к Главный ветка. Эти два рабочих процесса были почти идентичными копиями, за исключением той части, что Главный Рабочий процесс филиала включал шаг выпуска.

Теперь, после большого года, я заметил, что несколько рабочих процессов проектов, над которыми я работаю, условно настроили некоторые шаги в своем рабочем процессе. Я не уверен, но я думаю, что это не всегда так … или я полностью упустил, что это была возможность в документации, когда я первоначально настроил свои трубопроводы рабочего процесса.

Так почему я думаю, что это важно? Поскольку наличие одного рабочего процесса избегает дублирования и, таким образом, облегчает изменение рабочего процесса, например, использовать новую версию node.js или добавить дополнительный шаг.

Поэтому мне потребовалось некоторое время, чтобы объединить два рабочего процесса в один рабочий процесс. Чтобы сделать это правильно, мне нужно было несколько итераций и много сбоев, и именно поэтому я решил написать об этом небольшой пост. Рабочий процесс, с которым мы получим, будет работать в нескольких средах во время запроса на притяжение и будет включать в себя шаг условного выпуска, когда запрос на вытягивание объединен с Главный ветка.

Давайте погрузимся!

Решить, когда запускается рабочий процесс

Чтобы запустить рабочий процесс, необходимо определить триггеры. В моем случае я хочу, чтобы рабочий процесс работал, когда push случается с Главный ветвь, а также при открытии или изменении запроса на вытяжение.

name: ci

on:
  push:
    branches:
      - 'main'
  pull_request: {}

Задачи рабочего процесса

Затем нам нужно определить задачи рабочего процесса. Это делается путем добавления одного или нескольких Работа , который включает в себя шаги которые выполняются.

Для простого трубопровода CI/CD я предпочитаю просто придерживаться одной работы, потому что это проще. Если вы работаете над проектом, который включает в себя несколько задач, может быть лучше определить несколько заданий, так как они работают параллельно, и, таким образом, потребуется меньше времени, чтобы запустить.

Работа нуждается в среде для запуска ( Runs-on ), и она включает в себя шаги Это должно быть выполнено. Рабочий процесс проекта node.js может выглядеть как следующий рабочий процесс, который строит, тестирует и выпускает проект.

name: ci

on:
  push:
    branches:
      - 'main'
  pull_request: {}

jobs:
  build_test_release:
    runs-on: 'ubuntu-latest'

    steps:
      - uses: actions/checkout@v2
      - name: use Node.js
        uses: actions/setup-node@v2
      - name: install
        run: npm install
      - name: build
        run: npm run build
      - name: test
        run: npm run test
      - name: Release
        run: npx semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Но есть одна проблема с вышеупомянутым рабочим процессом, который является Выпуск шаг. Код будет выпущен каждый раз, когда работает рабочий процесс. Поскольку этот рабочий процесс также работает по запросам на привлечение, это означает, что мы отпустим нежелательные версии.

Условный шаг

В качестве исправления мы можем условно запустить шаг выпуска, используя Если выражение Анкет Исправление гарантирует, что этап выпуска будет вызван только на Главный ветвь, и только тогда, когда он запускается из нашего репозитория. Вторая проверка — это предосторожность, чтобы предотвратить раздвоенный репозиторий для случайного выпуска версии.

name: ci

on:
  push:
    branches:
      - 'main'
  pull_request: {}

jobs:
  build_test_release:
    runs-on: 'ubuntu-latest'

    steps:
      - uses: actions/checkout@v2
      - name: use Node.js
        uses: actions/setup-node@v2
      - name: install
        run: npm install
      - name: build
        run: npm run build
      - name: test
        run: npm run test
      - name: Release
        run: npx semantic-release
        if: github.ref == 'refs/heads/main' && github.repository == 'REPO_OWNER/REPO_NAME'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Пока все хорошо, и этот рабочий процесс может быть всем, что вам нужно.

Работа в нескольких средах

Если вы хотите поднять вещи на следующий уровень, рабочий процесс может быть настроен на запуск в нескольких средах и нескольких версиях Node.js. Здесь все заинтересовано в моем мнении, потому что это гарантирует, что другие участники и пользователи не сталкиваются с проблемами, специфичными для окружающей среды.

Чтобы определить различные среды, мы используем Стратегия матрица Синтаксис и укажите различные версии как массив. Этот массив присваивается пользовательской переменной, которая может использоваться в рабочем процессе.

Все шаги в работе выполняются для каждой возможной комбинации матрицы. В приведенном ниже примере это означает, что каждый шаг запускается в шесть раз, например, один раз на Ubuntu и Node.js версии 12, и в другое время в Windows и Node.js версии 12.

name: ci

on:
  push:
    branches:
      - 'main'
  pull_request: {}

jobs:
  build_test_release:
    strategy:
      matrix:
        node-version: [12, 14, 16]
        os: ['ubuntu-latest', 'windows-latest']
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v2
      - name: use Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}
      - name: install
        run: npm install
      - name: build
        run: npm run build
      - name: test
        run: npm run test
      - name: Release
        run: npx semantic-release
        if: github.ref == 'refs/heads/main' && github.repository == 'REPO_OWNER/REPO_NAME'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Но, как и раньше, есть улов. Если есть толчок к Главный Ветвь, релиз также будет вызван шесть раз. В результате шесть релизов. Мы могли бы расширить Если Выражение, чтобы включить версию node.js и версию ОС, но есть лучший способ.

Динамические версии

Запуск рабочего процесса более одного раза занимает некоторое время, и я думаю, что не нужно снова повторно запустить весь процесс сборки после объединения запроса на притяжение. Если запрос на тягу зеленый, мы можем предположить, что код готов к выпуске. Другими словами, нам не нужна матрица, когда Главный Рабочий процесс филиала запускается.

Чтобы сократить время, необходимое для выполнения рабочего процесса на Главный Ветвь Мы можем добавить только одну версию в матрицу. Это изменение в рабочем процессе также устраняет проблему с несколькими выпусками.

Чтобы реализовать это, мы можем динамически построить матрицу. Добавив проверку в контексте текущей ветви с github.ref Мы можем условно определить массив. Хитрость здесь состоит в том, чтобы определить массив как строку и использовать FromJson Метод Чтобы подготовить его к фактическому массиву, который мы можем использовать в рабочем процессе.

name: ci

on:
  push:
    branches:
      - 'main'
  pull_request: {}

jobs:
  build_test_release:
    strategy:
      matrix:
        node-version: ${{ fromJSON(github.ref == 'refs/heads/main' && '[16]' || '[12,14,16]') }}
        os: ${{ fromJSON(github.ref == 'refs/heads/main' && '["ubuntu-latest"]' || '["ubuntu-latest", "windows-latest"]') }}
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v2
      - name: use Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}
      - name: install
        run: npm install
      - name: build
        run: npm run build
      - name: test
        run: npm run test
      - name: Release
        run: npx semantic-release
        if: github.ref == 'refs/heads/main' && github.repository == 'REPO_OWNER/REPO_NAME'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Конечный результат

И вуаля, теперь у нас есть один рабочий процесс, который учитывает контекст, чтобы начать правильные шаги в рабочем процессе. По запросу на привлечение код тестируется в нескольких средах, чтобы дать нам всю уверенность, необходимую для выпуска. Пока толчок к Главный Branch запускает рабочий процесс только в одной конкретной среде, а также включает в себя условное этап выпуска.

Вывод

Я рад видеть, что будущее принесет с динамическими рабочими процессами, потому что код может быть протестирован с несколькими версиями библиотеки, чтобы обеспечить обратную совместимость. Необходимость делать это вручную требует большой работы и может быть даже невозможна. Примеры этого — Eslint-Plugin-Testing-Library Pipeline который проверяет различные правила Eslint с различными версиями Eslint и Агулярные версии-действие которое является действием GitHub для запуска рабочего процесса на нескольких угловых версиях. Как это аккуратно!

Следуйте за мной в Твиттере в @Tim_deschryver | Подписаться на Информационный бюллетень | Первоначально опубликовано на Timdeschryver.dev Анкет

Оригинал: «https://dev.to/this-is-learning/how-to-set-up-a-dynamic-ci-cd-pipeline-with-github-actions-29ah»