Actions checkout v2 что делает
Перейти к содержимому

Actions checkout v2 что делает

  • автор:

GitHub — jobs : what is : use actions/checkout

For this line: uses : «actions/checkout@something» , it will use the actions/checkout github action (source here) with the ref something . This ref only refers to the github action version (nothing to do with your repo)

The uses statement refers to a github action that is being used in this step. From github documentation for jobs..steps[*].uses :

Selects an action to run as part of a step in your job. An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image.

This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.

By default it checks out only one commit. My understanding is that it’s doing something similar to:

git fetch --depth 1 origin $GITHUB_REF 

This action also persists an auth token in git config. This way, your workflow can run authenticated git commands

By default, it clones your current repository ( > ) but you can also use this action to clone a different repository, and specify additionnal parameters like token , branch , path etc.

An example with additionnal input parameters: check out all git history by setting fetch-depth to 0 (default is 1 ), see usage doc:

- uses: actions/checkout@v2 with: fetch-depth: 0 

answered Apr 16, 2021 at 23:02
Bertrand Martel Bertrand Martel
43.2k 16 16 gold badges 138 138 silver badges 160 160 bronze badges

«This action checks-out your repository under $GITHUB_WORKSPACE,» What does this mean? I thought you could only checkout a branch not a repository.

Jun 22 at 20:13
Why name the action as checkout when its actually running git fetch command?
Aug 27 at 9:07

Understanding terminologies made things clearer

  • Remote repo — It can also be referred to as the origin
  • Origin — the default name of the remote repo or the source repo being cloned
  • Head — a reference to human-friendly names for branches
  • git checkout — switch to a particular branch and displaying the changes currently on that branch
  • origin/name_of_branch — branch name created when fetching changes from a particular branch on the remote repo

Side Note: When git fetch is used, a custom branch is created locally in the form «origin/name_of_branch», changes on this branch can be viewed locally. These changes are the updated version of the files, not the specific change in that file as seen when commits are being inspected on GitHub.

Back to the question When the action is executed

jobs: myjob: steps: - name: checkout uses: "actions/checkout@something" - . 

The default steps being executed are:

  1. The current repo in which the workflow is being triggered gets cloned.
  2. Depending on the defined events such as a push or pull request:
  • For a push event, it runs the command below, where $GITHUB_REF points to the latest commit on the specified branch for the push event in the workflow.
git fetch --depth 1 $GITHUB_REF 
  • For pull requests, it checks $GITHUB_REF points to the latest commit on the pull request source branch. This means it points to the would-be code/result from merging the pull request. This is the code/result other steps within the job are executed on such as running builds or tests. (Not completely sure of the command which runs under the hood)

Environment variables being referenced in the commands are explained here. Additional options can be added to implement specific processes or scenarios such as checking out a different branch. This can be found in the official repo readme.

Github Actions. Простой пример для уверенного знакомства

Здесь я буду рассказывать о моем опыте настройки CI/CD c помощью GitHub Actions.

Эта статья поможет тем, кто хочет настроить автоматический деплой для личного/учебного проекта на свой удаленный сервер, пользуясь бесплатным сервисом GitHub Actions (ограничения, естественно, имеются в соответствии с тарифным планом Free, в личных нуждах должно хватить за глаза). Причем этим сервисом можно пользоваться бесплатно даже с приватным репозиторием (на момент написания статьи).

Акцентирую на тех моментах, которые для меня оказались не самыми очевидными, читая краткое руководство от Github.

Предполагается, что вы уже знаете как пользоваться Github. По большому счету не важно, какой у вас язык программирования или стек: главное — понять, как работают Github Actions и уметь применить его для любого проекта.

1. Workflow файлы

Начнем с создания workflow файла, с помощью которого Github запускает Actions. На вкладке Actions на странице репозитория на базе вашего кода Github предлагает разные шаблоны workflow файла, начнем с Simple workflow.

Шаблон

После нажатия на кнопку Configure вы увидите содержимое файла.

Пример базового workflow файла simple.yml

name: CI on: # События, которые запускают jobs push: branches: [ "main" ] pull_request: branches: [ "main" ] # jobs запускаются параллельно, если не указана последовательность jobs: # Название job вы можете назвать как угодно my_build_job: # Операционная система в виртуальной машине, в которой запускаются процессы runs-on: ubuntu-latest # Шаги steps: # Actions от github: проверяет репозиторий, гит и т.д. - uses: actions/checkout@v3 # Пример однолинейного простого скрипта shell - name: Run a one-line script run: echo Hello, world! # Пример многолинейного скрипта shell - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project.

Читаю файл: workflow файл запускает jobs с названием my_build_job при событиях отправки кода в репозиторий и создания Pull Request на ветке main . my_build_job запускается на ОС Ubuntu, использует action с названием actions/checkout@v3 и выполняет 2 шага: пишут в консоль однострочный и многостроный тексты.

После создания name-of-your-wokflow-file.yml файла, в репозиторий у вас появится папка c файлом .github/workflows/name-of-your-wokflow-file.yml . Workflow файлов можно создавать несколько.

Итак, смысл состоит в том, чтоб запустить процессы при определенном действий на выбранной вами ветке.

Например, «сделать деплой» — значит нам нужно запустить процессы:

  • проверка кода линтером,
  • запуск тестов проекта,
  • получение изменений в файлах в папке проекта на удаленном сервере, перезапуск каких-то сервисов проекта (контейнеров, перезапись папок/файлов) на удаленном сервере, чтоб изменения вступили в силу.

А если написать с учетом workflow файла, более подробно эта последовательность будет такова:

  • Github создает виртуальную машину с выбранной вами операционной системой.
  • Проверяет ваш репозиторий: его наличие, git, нужные ветки, авторизацию.
  • Копирует в эту операционную систему ваш репозиторий после успешной проверки
  • Запускает проверку кода, тесты.
  • Отправляет изменения, которые вы внесли в ваш репозиторий, на ваш удаленный сервер.
  • Делает действия для вступления в силу ваших изменений на вашем сайте.

Обычно проверку кода, запуск тестов и деплой разделяют на отдельные job , которые запускают отдельные runners. Раннер — это сервер, который запускает одну job .

2. Actions

Самое интересное в workflow-файле — actions в строке uses . В простейшем примере выше это — actions/checkout@v3. Можно посмотреть в исходном коде, что делает action . Но проще посмотреть на странице выполнения job , после того, как вы его запустите:

Запускаемые процессы actions/checkout@v3

  • копирует переменные внутрь контейнера
  • проверяет версию git , создает папки нужные, пишет файл настройки
  • проверяет репозиторий
  • авторизируется
  • копирует репозиторий внутрь контейнера
  • переходит на ветку main

Существует множество actions , созданные разработчиками, которые можно использовать, выбрав нужный на Github Marketplace.

Например, в своих нуждах я использовала D3rHase/ssh-command-action@v0.2.2, который запускает мою консольную команду через ssh на удаленном сервере.

3. Мой пример

Мой проект-пример создан генератором Ruby on Rails, потому что примеры без начинки не являются примерами. Я выбрала шаблонный workflow-файл из предложенных Github и дописала его под свои нужды.

Мой примерный список требуемых действии для CI/CD. В файле rubyonrails.yml последовательность процессов такая:

  1. Проверила линтером код.
  2. Запустила тесты.
  3. Действия на удаленном сервере:
    1. Переход в папку с проектом.
    2. Получение изменений из репозитория используя git pull.
    3. Пересоздание docker контейнеров с проектом

    У вас действия могут быть другие. Например, если проект — это браузерное клиентское приложение, то нужно сгенерировать конечные файлы с командой npm run build и скопировать файлы в определенную папку на удаленном сервере, из которой кушает уже настроенный nginx. В этом случае для копирования подошел бы garygrossgarten/github-action-scp@v1.0

    Мой пример .github/workflows/rubyonrails.yml

    # This workflow will install a prebuilt Ruby version, install dependencies, and # run tests and linters. Then it pulls new features from my repo and # rebuild containers on remote server through ssh. name: "Ruby on Rails CI" on: push: branches: ["main"] pull_request: branches: ["main"] jobs: lint: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Install Ruby and gems uses: ruby/setup-ruby@ee2113536afb7f793eed4ce60e8d3b26db912da4 # v1.127.0 with: bundler-cache: true - name: Lint Ruby files run: bundle exec rubocop test: needs: lint runs-on: ubuntu-latest services: postgres: image: postgres:14 ports: - "5432:5432" env: POSTGRES_DB: rails_test POSTGRES_USER: rails POSTGRES_PASSWORD: password env: POSTGRES_DB: rails_test POSTGRES_USER: rails POSTGRES_PASSWORD: password RAILS_ENV: test DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test" steps: - name: Checkout code uses: actions/checkout@v3 - name: Install Ruby and gems uses: ruby/setup-ruby@ee2113536afb7f793eed4ce60e8d3b26db912da4 # v1.127.0 with: bundler-cache: true - name: Set up database schema run: bin/rails db:schema:load - name: Run tests run: | bundle exec rake db:drop db:create db:migrate db:seed; bin/rake test; deploy: needs: test runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Checkout code uses: actions/checkout@v3 - name: Install Ruby and gems uses: ruby/setup-ruby@ee2113536afb7f793eed4ce60e8d3b26db912da4 # v1.127.0 with: bundler-cache: true - name: Run command on remote server uses: D3rHase/ssh-command-action@v0.2.2 with: host: $> user: $> private_key: $> command: | cd $>; git checkout main; git pull; docker-compose --file docker-compose.prod.yml down; docker-compose --file docker-compose.prod.yml up -d; docker system prune --all --force;

    Workflow файл запускается при внесении изменений или создании Pull Request на ветке main . Выполняю 3 jobs с названиями lint , test и deploy Каждый раннер запускается в Ubuntu, проверяет репозиторий с помощью actions/checkout@v3 , устанавливает Ruby и нужные библиотеки с помощью ruby/setup-ruby@ee2113536afb7f793eed4ce60e8d3b26db912da4 . Линтер проверяет код с помощью библотеки rubocop . Для тестов мне нужна база данных, она запускается сервисом postgres с тестовыми переменными окружения. На этом шаге также проверяется схема БД, запускаются сиды и, собственно, сами тесты. Шаг deploy я выполняю только на ветке `main`. Здесь вы можете видеть какие консольные команды выполняются на удаленном сервере с помощью action D3rHase/ssh-command-action@v0.2.2. Далее перехожу в папку с проектом на удаленном сервере, перехожу на ветку main , притягиваю изменения из репозитория, перезапускаю docker сервисы, чищу лишнее, связанное с docker.

    Как вы понимаете, на моем удаленном сервере предварительно настроен git, docker, docker-compose, Github подружен с сервером с помощью SSH-ключа.

    Раннеры выполняются последовательно, для этого используется ключевое слово needs в теле job .

    Визуально раннеры на Github выглядят симпатично и интуитивно понятно.

    Вид из интерфейса на jobs

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

    Пример job на этапе настройки процесса

    - name: Run command on remote server uses: D3rHase/ssh-command-action@v0.2.2 with: host: $> user: $> private_key: $> command: | echo '--- START WORK ON REMOTE SERVER ---'; cd $>; echo '--- LIST OF FILES ---'; ls -al; echo '--- GIT INFORMATION ---' git co dev; git pull; echo '--- DOCKER OPERATIONS ---'; docker-compose down; echo '--- LIST OF DOCKER CONTAINERS AFTER STOPING DOCKER CONTAINERS ---'; docker ps; docker-compose --file docker-compose.prod.yml up -d; docker system prune --all --force; echo '--- LIST OF DOCKER CONTAINERS AFTER STARTING DOCKER CONTAINERS ---'; docker ps;

    После настройки процесса CI/CD можно удалить лишнее.

    4. Secrets

    В rubyinrails.yml файле вы могли заметить переменные, которые вызываются из объекта secrets . Эти переменные нужны для того, чтобы подружить ваш удаленный сервер с создающимися контейнерами на Github на время выполнения действии. Для этого я сделала шаги:

    1. Сгенерировала SSH ключ на удаленном сервере:
    cd ~/.ssh; ssh-keygen -t ed25519 -C "your_email@example.com"

    Скажем, я назвала созданные файлы test и получила 2 файла — приватный и публичные ключи.

    Публичный и приватные ssh-ключи

    1. Содержимое приватного ключа я скопировала в переменную в SSH_PRIVATE_KEY во вкладке Settings -> Secrets -> Actions:
    2. Создала еще переменные SSH_HOST и SSH_USER , PROJECT_FOLDER с соответствующим содержимым.

    Секретные переменные репозитория для actions

    Заключение

    Итого по статье показано:

    • Как создавать workflow.yml файлы, которые будут запускать нужные вам действия.
    • Где и как искать нужные вам actions или самому написать однострочный или многстрочный bash-скрипт, если задача простая.
    • Где хранить секретные переменные, которые вы можете использовать в вашем workflow файле.
    • Как дебажить в случае ошибок.

    Удовольствия вам от программирования!

    Github actions: базовые понятия

    Что это такое и как удаленно прогонять тесты на каждый пуш при помощи одного крошечного конфига

    6 min read
    Jul 13, 2020

    Что такое github actions вообще?

    Это указание гитхабу запускать какой-то код каждый раз когда случается некое событие. Push, создание PR, таймер, внешнее событие, а также всякие другие.
    Где запускается этот код? На виртуальных машинах гитхаба(но при желании можно и на своих гонять). Удобно, можно ничего не настраивать.
    Что он делает? Да что угодно, насколько хватит фантазии, главное — позволяет автоматизировать какие-то действия, нужные для вашего процесса разработки: гонять тесты, собирать и деплоить продукты, собирать статистику, оповещать людей.

    Таким образом github предоставляет возможность не только прикрутить неплохой бесплатный CI/CD(как раньше умел только gitlab, о котором у меня тоже была статья), но и создать очень гибкую и легко конфигурируемую систему поддержки разработки.

    Тут все восхитительно просто.

    Для начала нужно придумать, что же хочется сделать. Потом найти готовый экшен/несколько, которые позволят это сделать. Их проще всего искать в github marketplace — по сути это просто список репозиториев, которые подали заявку, чтобы быть там. На самом деле вы будете ссылаться на конкретный репозиторий конкретного пользователя.

    Если подходящие готовые не находятся, всегда можно написать свой. Это очень просто. Я, например, написала экшен, чтобы интегрировать jira в пулл-реквесты:

    jira-description — GitHub Marketplace

    A lightweight solution to integrate GitHub with JIRA for project management. �� To make jira-description-action a part…

    Пока что давайте разберем самый простой пример — пусть на каждый пуш в любой ветке гоняются тесты(пример будет про js-разработку)

    В первую очередь нужно создать в своем проекте папку .github, а в ней папку. workflows, а в ней файл name-matters-only-for-you.yaml

    контент у него будет такой:

    name: 'test my project'
    on:
    push:
    pull-request:
    jobs:
    test-job:
    runs-on: ubuntu-16.04
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-node@v1
    name: 'setup node'
    with:
    node-version: '13.x'

    - name: 'install'
    run: npm i

    - name: 'test'
    run: npm run test

    Тогда в интерфейсе гитхаба прогоны будут выглядеть вот так:

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

    # имя, чтобы отображалось в интерфейсе
    name: 'test my project'
    # тут список событий, на который экшен должен запускаться
    on:
    push: # пусть гоняется на любой пуш
    pull-request: # и на пулл-реквест
    # список того, что нужно делать. каждый job будет выводиться отдельным элементом слева UI
    jobs:
    test-job: # uniqe id
    runs-on: ubuntu-16.04 # на какой машине гонять
    steps: # список шагов, разберем подробнее отдельно ниже
    - uses: actions/checkout@v2
    .

    Steps

    1. Весь конфиг пишется в yaml, поэтому важно следовать синтаксису и следить за отступами, новая сущность в списке начинается с –
    2. Шаги — это по сути упорядоченный список. Они будут выполняться один за одним строго последовательно

    Посмотрим еще раз на конфиг, тут видно, что у нас 4 шага, только у них почему-то разный набор параметров, как это работает?

    steps: 
    - uses: actions/checkout@v2
    - uses: actions/setup-node@v1
    name: 'setup node'
    with:
    node-version: '13.x'

    - name: 'install'
    run: npm i

    - name: 'test'
    run: npm run test
    • name нужен просто для отображения в интерфейсе, без него прекрасно можно обойтись
    • uses тут указываем имя какого-то уже написанного экшена, если хотим его использовать. Экшен может быть конкретным бранчем в конкретном репозитории(любом), может быть вообще кодом, лежащим в соседней папке, а может быть и вовсе docker-image(полный список)
      В примере используется actions/checkout@v2 и actions/setup-node@v1 . По названию легко можно найти их в marketplace, посмотреть исходный код конкретной версии(она идет после @ в названии) и понять, что они делают. checkout делает pull репозитория и ветки, в котором запущен. Таким образом мы получаем доступ к коду. Без этого экшена делать npm i было бы не на чем.
      setup-node устанавливает ноду, чтобы мы могли дальше использовать ее
    • with если шаг использует экшен, то иногда в него хочется передать параметры. Параметры регламентированы самим экшеном. В примере мы можем указать версию ноды, необходимую для нашего проекта
    • run запускает какую-то команду в shell. Использовать shell-команду вместе с экшеном не получится, они должны жить в разных шагах

    После того, как этот файл добавлен и запушен в master, на каждый дальнейший пуш будет прогоняться наш скрипт с тестами.
    Если это был просто пуш, результат можно будет увидеть в списке коммитов. Если пулл-реквест — в саммари внизу

    Вот и все, разобрали маленький пример, ура, можно дерзать!
    Чтобы было проще, собрала список вещей, которые узнала, когда дерзала сама

    Более сложные вопросы:

    Как передать какой-нибудь токен, нигде его не публикуя? Или что такое secrets в конфигах?

    Всякие токены доступа, опубликованные в публичном доступе, это большой риск для вашей секьюрности. Как передавать их в зашифрованном виде? Гитхаб уже позаботился об этом, создав secrets. Их можно найти в любом репозитории: settings -> secrets. Там можно создать секрет с почти любым именем, например, MY_TOKEN, добавить к нему значение, и тогда в любом экшене можно будет написать secrets.MY_TOKEN , и это значение будет использоваться

    Прикольные вещи:
    1. Один раз создав и сохранив секрет, посмотреть его значение будет уже нельзя, только обновить
    2. Если попытаться вывести значение секрета в логах или внутри кода экшена, выведется ***
    3. Однако лучше не логгировать секреты вообще, так как любую защиту такого рода все же можно обойти

    Как добавить secrets.GITHUB_TOKEN, который нужен в конфиге?

    Все секреты с именами, начинающимися на GITHUB — служебные и подставляются гитхабом автоматически. Можно не переживать, просто напишите > и все будет работать

    Как сделать так, чтобы нельзя было замержить пулл-реквест если тесты упали?

    Нужно пойти в настройки репозитория и у становить там правила для мержа в master, выбрав галочкой workflow, содержащий важные тесты

    Как передать результат работы одного шага в другой шаг?

    Это очень классная фича! При помощи кода ниже я проверяю, есть ли измененные файлы после билда в папке lib и, если есть, делаю коммит с обновленной сборкой. Переменные, добавленные в шаге, доступны в любом следующем шаге этого же job

    - name: "check if build has changed" 
    run: echo ::set-env name=DIFF::$(git diff --stat -- 'lib')

    - name: "Commit files"
    if: $>
    run: git commit -m "build action" -a

    Как передать результат работы между джобами?

    Тут немного веселее!

    jobs: 
    first-job:
    - name: "check if build has changed"
    id: has-diff
    run: echo ::set-output name=DIFF::$(git diff --stat -- 'lib')

    outputs:
    diff_output: $>

    second-job:
    needs: build-test
    steps:
    - name: "print diff"
    run: echo "$>"

    Важно помнить, что и output, и env-параметры это строки, которые могут содержать специальные символы. Поэтому при выводе в консоль необходимо это учитывать, иначе можно получить вот такую ошибку, если написать run: echo $> без кавычек:

    Если информации в этой статье не хватило для того, чтобы реализовать то, что вам нужно, возможно, пришло время написать собственный экшен:

    Экшены — Непрерывная интеграция (CI)

    Одна из самых классных вещей в Github Action – экшены. С их помощью значительно сокращается количество кода в воркфлоу, а стандартный цикл сборки и тестирования проходит буквально за минуты на любом стеке.

    В предыдущих уроках мы уже встречались с несколькими экшенами. Чаще всего в сборках используется экшен checkout, который клонирует репозиторий в рабочую директорию:

    steps: - uses: actions/checkout@v3 

    Отметим несколько деталей. Экшен работает как один из шагов задания. Для этого вместо ключа run используется ключ uses , за которым идет имя экшена. Откуда берется это имя? Из каталога экшенов . Причем там могут быть как встроенные Github Actions, так и созданные сторонними пользователями. Понять, что и откуда можно по имени экшена, оно соответствует структуре ссылок самого Github: имя пользователя или команды/название репозитория. Встроенные экшены находятся в команде actions.

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

    У экшена могут быть параметры. Они задаются через ключ with :

    steps: - uses: actions/checkout@v3 # https://github.com/actions/setup-node - uses: actions/setup-node@v3 with: node-version: '18.x' cache: 'npm' # ускоряет повторные сборки - run: npm ci - run: npm test 

    А вот пример стороннего экшена , который запускает тесты на фреймворке cypress:

    name: End-to-end tests on: [push] jobs: cypress-run: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 

    Открыть доступ

    Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

    • 130 курсов, 2000+ часов теории
    • 1000 практических заданий в браузере
    • 360 000 студентов

    Наши выпускники работают в компаниях:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *