Линтер на все случаи жизни — GitHub Super Linter


    Команда DevOps инженеров из GitHub поделились своим универсальным решением для проверки качества кода. С ним можно настроить линтер для 17 языков всего в 11 строк:


    name: Lint Code Base
    on:
      push:
        branches-ignore:
          - 'master'
    jobs:
      linter:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2
            - uses: docker://github/super-linter:v2.1.0

    Код выше является YAML конфигурацией для GitHub Actions (бесплатный CI/CD от GitHub) и далее мы разберемся с его содержимым и принципом работы.


    Мотивация


    Данный проект изначально является внутренней разработкой GitHub:


    GitHub Super Linter был создан командой DevOps GitHub Services для обеспечения согласованности нашей документации и кода для повышения продуктивности взаимодействия и совместной работы в компании.
    Лукас Гравли, 2020

    Проблема


    1. Для каждого языка существует отдельный линтер, а иногда несколько
    2. В каждой экосистеме настройка линтера отличается

    Настройка линтера это важная часть любого проекта, с более чем 1 участником. Он помогает приводить код к единому стандарту, во избежание недопониманий и разногласий между разработчиками.


    Я могу судить из мира JS, где настройка линтера и CI/CD занимает 10-20 минут. Устанавливаем eslint (обычно в связке с prettier), и настраиваем список правил. Ничего сложного, но то версия eslint обновилась, то какой-то плагин нужно доустановить, то транспайлер ругается, в общем оставшиеся 9 минут 30 секунд занимаешься отладкой.


    Не так уж и страшно и даже полезно потратить 10 минут на ручную настройку, но только вот в случае с монорепо, это превращается в ад. Я не являюсь сторонником использования монореп, но они есть и с ними нужно жить и работать ¯\(ツ)


    Решение


    Обнародованный в open source super-linter интегрированный в CI/CD может автоматически определять и проверять код на следующих языках:



    Следовательно, если в проекте наблюдается смешивание стеков, то вполне рекомендуется посмотреть в сторону super-linter. Достаточно спорный момент насчет его использования в проектах с одним языком/фреймворком. Проекты с претензией на универсальность всегда несут за собой ограничения и потерю гибкости. Вопрос подбора решения немного из области философии, выбор глубины требуемой абстракции может пасть на низкоуровневый ассемблер, или же остановится на JS. Я бы исходил из задачи:


    • нет времени объяснять, нужен линтер за 30 секунд — подключили super-linter
    • можно продумать список правил и подстроить под текущее окружение — я бы пробовал точечное решение

    Реализация


    GitHub Super Linter — это репозиторий исходного кода, упакованный в контейнер Docker и вызываемый из GitHub Actions.


    Принцип работы


    При триггере CI/CD выполняется workflow, описанный конфигом из начала статьи:


    # Название
    name: Lint Code Base
    # Определение триггера для запуска CI/CD
    on:
      # Триггер на push любого коммита в ветку
      push:
        # Игнорирование ветки `master`
        branches-ignore:
          - 'master'
    # Задачи к выполнению
    jobs:
      # Задача
      linter:
        # Сборка окружения ubuntu-latest
        runs-on: ubuntu-latest
        # Шаги задачи
        steps:
          # Переключение на текущую ветку (обязательное действие, если нужен доступ к файлам репозитория)
          - uses: actions/checkout@v2
          # Вызов Super Linter
          - uses: docker://github/super-linter:v2.1.0


    Только последняя строка вызывает super-linter, и дальше мяч переходит на его сторону. Внутри происходит примерно следующее:


    1. Поднимается Docker-контейнер и устанавливает в себя требуемые окружения с соответствующими линтерами
    2. Следом собираются все переданные данные о правилах и настройках
    3. Запускается Bash скрипт,
      • собирает переданный конфиг
      • анализирует файлы на принадлежность к языку/фреймворку (по расширению файла)
      • запускает соответствующий линтер на каждом файле
      • генерирует отчет

    До банальности просто и работает:



    NOTE: Я например для реализации такого же функционала настраивал CI на работу с конкретными папками, содержащими тот или иной тип файлов. У меня не было таких случаев, чтобы в папке с JS, обнаруживались файлы .cs. Работало так же, и пожалуй более оптимизировано, чем перебор всех файлов, но кто я такой против GitHub DevOps team ;)

    Конфигурация


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


    • нет возможности настраивать версии используемых окружения и линтера
    • нет доступа к package.json (JS/TS)
    • невозможно установить или загрузить ресурсы из закрытых источников (приватные репозитории, частные регистры)

    Вывод


    Стратегия Microsoft(GitHub) — публиковать свои наработки в open source очень похвальная затея, хотя у некоторых возникают сомнения на этот счет. Результатом таких действий является и GitHub Super Linter. На мой взгляд это не что-то революционное, а просто еще один проект на GitHub, но с отметкой made with ♡ in GitHub.


    P.S. Использование standardjs в качестве линтера для JS/TS в 2020 году, это как-то обескураживает. Думаю это объяснимо тем, что GitHub === enterprise === legacy, и код опубликован как есть, вот и получили технологию 5-летней давности. Уже создан issue, предлагаю поддержать или даже поконтрибьютить.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 22

      +3

      Настроили линтер за 20 минут в монорепе? Это, батенька, карго-культ называется.

        +3
        Осторожно, грубый юмор!
        Я не любитель насилия (и, тем более, не профессионал), но за некоторые жаргонизмы хочется дать в монорепу или в монобубен

        P.S. данный комментарий — лишь ограниченно уместная шутка и на самом деле не выражает никаких явных или неявных желаний кроме желания пошутить
          0

          А что этим линтером можно проверять? Количество отступов и переносов?

            –1

            Всё то же, что вы проверяете обычным линтером. Это же просто сборная солянка всех линтеров с окружениями

            +1

            Для C и C++ нет. А можете порекомендовать линтер для них?

            +4
            Без отдельного докера уже проверку кода сделать невозможно. Я все правильно прочитал в статье?
              0

              Всё правильно, технологии ради технологий, но опять-таки:


              кто я такой против GitHub DevOps team ;)
                0
                возможно конечно, вы, конечно, можете сами написать скрипт который скачает/распакует/установит нужный вам линтер
                  0

                  Не берусь утверждать за другие экосистемы, но да, в мире JS/TS это занимает 10 минут без докеров

                +2
                Ммм, а как с этим на практике работать?

                Из статьи, как я понял, я узнаю о проблемах в коде только после пуша коммита в origin. Спасибо, конечно, но с ESLint я узнаю о проблемах в коде ещё до пуша коммита.
                  0
                  > а как с этим на практике работать?
                  например, запретить мерж пулл реквеста если код не проходит валидацию.
                    0
                    И чтобы узнать всё ли я поправил каждый раз пушить? Такое себе.
                      +1
                      акцент не в том месте, это просто внешняя проверка, никто ж не знает что вы у себя локально запускаете.
                        0
                        А как мне локально развернуть внутреннюю проверку? А то получается ситуация «тестим на проде».
                          0
                          конкретно этот образ вряд ли имеет смысл запускать локально, он завязан на переменные окружения доступные в github actions (почему не сделали его переносимым — другой вопрос)
                        0

                        Привычный путь разработки это:


                        1. Сделал изменения в отдельной ветке
                        2. Протестировал (по желанию) локально
                        3. Запушил в origin
                        4. Сделал PR
                        5. PR проверяется средствами CI/CD + Code Review

                        Другой вопрос, что с этим линтером нельзя проверить локально (шаг 2), но это издержки реализации. Я повторюсь, я не писал этот скрипт, и я сомневаюсь что его имеет смысл применять на обычных проектах без смешанного стека. Если у вас монорепо, то так или иначе пришлось бы думать в сторону такого же решения, или ставить все окружения на машины всех членов команды.

                    +2

                    Кажется выражение "натягивать сову на глобус", здесь уместно. Настройка линтера делается один раз, правила хранятся в гите, как и инструкции/скрипты для эксплуатации в ide.

                      +1
                      Java в списке языков нет… иду мимо.

                      Only users with full accounts can post comments. Log in, please.