Синтаксис workflow
Info
Разберемся в синтаксе создания workflow.
Файлы workflow на GitVerse должны:
- быть написаны в синтаксисе YAML;
- располагаться в .gitverse/workflows/ вашего репозитория, но раннер также обработает и .yaml-файлы в директории .github/workflows/.
name
Название workflow, которое отображается в интерфейсе GitVerse для идентификации, используется для фильтрации запусков на вкладке «CI/CD».
run-name
Название конкретного запуска, которое помогает различать разные запуски, особенно при использовании параметризованных workflow.
run-name: Deploy to dev by @${{ gitverse.actor }}on
Раздел, определяющий тригеры, при которых workflow будет запущен. Примеры событий включают push, pull_request, workflow_dispatch и другие.
on: pushon: [push, fork] # Запускается по пушу или форку# workflow для отслеживания форков
name: Trigger fork
on:
fork: # Создание форка репозитория
jobs:
notify-fork:
name: Notify about New Forks
runs-on: ubuntu-latest
steps:
- name: Log fork event
run: |
echo "Trigger: ${{ gitverse.event_name }}"
echo "Actor (who forked): ${{ gitverse.actor }}"
echo "Fork details: ${{ gitverse.event.forkee.full_name }}"
echo "Created at: ${{ gitverse.event.forkee.created_at }}"name: Trigger push
on:
push:
branches:
- master # Запускается по пушу в ветку masteron.<event_name>.types
Уточняет типы событий, на которые реагирует workflow. Например, для релиза можно указать published, edited.
# Указание типа с переносом по строкам
name: Trigger release
on:
release:
types:
- published
- editedon.<pull_request|pull_request_target>.<branches|branches-ignore>
Фильтрует запросы на слияние по веткам. Используйте branches для включения или branches-ignore для исключения определенных веток.
# Триггер для события pull_request
name: Trigger pull_request
on:
pull_request: # запрос на слияние
# если types не указан, workflow будет срабатывать на все типы событий триггера
types:
- opened # открыт
- edited # отредактирован
- closed # закрыт
- reopened # повторно открыт
- synchronize # синхронизирован
# в настоящее время не поддерживается:
# - assigned # назначен
# - unassigned # назначение отменено
# - review_requested # запрос на ревью
# - review_request_removed # запрос на ревью отменен
# - converted_to_draft # преобразован в черновик
# - ready_for_review # готов к ревью
# - locked # заблокирован
# - unlocked # разблокирован
# - labeled # помечен меткой
# - unlabeled # метка удалена
# - auto_merge_enabled # автоматическое слияние включено
# - auto_merge_disabled # автоматическое слияние отключено
branches:
- master
jobs:
build-test:
name: pull_request
runs-on: 'ubuntu-latest'
steps:
- name: Log PR event
run: |
echo "Trigger: ${{ gitverse.event_name }}"
echo "Action: ${{ gitverse.event.action || 'N/A' }}"
echo "PR #${{ gitverse.event.pull_request.number || gitverse.event.issue.number }}"
echo "Actor: ${{ gitverse.actor }}"on:
pull_request:
branches-ignore: # исключаем ветки
- 'releases/**-alpha'on:
pull_request:
branches:
- 'releases/**'
- '!releases/**-alpha' # исключаем веткиon.push.<branches|tags|branches-ignore|tags-ignore>
Настройка триггеров на события push с фильтрами по веткам или тегам.
name: Trigger push
on:
push:
branches:
- master
tags:
- v[0-9]+.[0-9]+.[0-9]+ # В фильтры можно добавлять регулярные выраженияon:
push:
branches:
- 'releases/**'
- '!releases/**-alpha'on.<push|pull_request|pull_request_target>.<paths|paths-ignore>
Определяет, какие изменения в репозитории должны вызывать workflow, фильтруя по типам файлов или папкам.
on:
push:
paths:
- '**.js' # срабатывает при пуше js-файловon:
push:
paths-ignore:
- 'docs/**' # срабатывает при пуше по опредленному путиon:
push:
paths:
- 'sub-project/**'
- '!sub-project/docs/**' # исключаем поддиректорию из правила на пуш# Пример workflow для пуша с фильтрацией
name: Trigger push
on:
push:
branches:
- master
tags:
- v[0-9]+.[0-9]+.[0-9]+
paths:
- src/**
branches-ignore:
- gv-pages
tags-ignore:
- beta*
paths-ignore:
- "!src/test/**"
jobs:
monitor-push:
name: Push Notification
runs-on: ubuntu-latest
steps:
- name: Log Push Details
run: |
echo "Trigger: ${{ gitverse.event_name }}"
echo "Branch Name: ${{ gitverse.head_ref || gitverse.ref }}"
echo "Commit SHA: ${{ gitverse.sha }}"
echo "Pusher: ${{ gitverse.actor }}"on.schedule
Позволяет планировать запуск workflow по расписанию, используя cron-like синтаксис.
name: Trigger schedule
on:
schedule:
# Запуск каждый день в 9:00 по UTC
- cron: "0 9 * * *"
jobs:
cleanup:
name: Cleanup Job
runs-on: ubuntu-latest
steps:
- name: Log Schedule Details
run: |
echo "Trigger: ${{ gitverse.event_name }}"
echo "Schedule cron: ${{ gitverse.event.cron }}"Info
Для облачных раннеров минимальный интервал — 15 минут, для локальных и организационных — 5 минут.
on.workflow_call
Триггер для вызова этого workflow из другого workflow.
Info
Можно вызывать workflow из приватных репозиториев внутри одной организации.
on.workflow_call.inputs
Определяет входные параметры, передаваемые при вызове workflow.
name: Trigger workflow_call
on:
workflow_call:
inputs:
message:
description: "Сообщение для вывода"
required: false
default: "Hello from reusable workflow!"
jobs:
echo-message:
runs-on: ubuntu-latest
steps:
- name: Print input message in base job
run: echo "${{ inputs.message }}"on.workflow_call.inputs.<input_id>.type
Указывает тип входного параметра, например, строка или число.
on.workflow_call.outputs
Определяет выходные параметры, возвращаемые после выполнения workflow.
on:
workflow_call:
# Маппинг выходных параметров workflow и заданий
outputs:
workflow_output1:
description: "The first job output"
value: ${{ jobs.my_job.outputs.job_output1 }}
workflow_output2:
description: "The second job output"
value: ${{ jobs.my_job.outputs.job_output2 }}on.workflow_call.secrets
Секреты, передаваемые при вызове workflow.
on:
workflow_call:
secrets:
access-token:
description: 'Токен, передаваемый из вызывабщего workflow'
required: false
jobs:
pass-secret-to-action:
runs-on: ubuntu-latest
steps:
# Передайте полученный секрет в действие
- name: Передача секрета в action
uses: ./.gitverse/actions/my-action
with:
token: ${{ secrets.access-token }}
# Передача секрета во вложенный многоразовый workflow
pass-secret-to-workflow:
uses: ./.gitverse/workflows/my-workflow
secrets:
token: ${{ secrets.access-token }}on.workflow_call.secrets.<secret_id>
Конкретный секрет, используемый при вызове workflow.
on.workflow_call.secrets.<secret_id>.required
Обозначает, что секрет является обязательным для выполнения workflow.
on.workflow_dispatch
Триггер для ручного запуска workflow через API или интерфейс.
on.workflow_dispatch.inputs
Определяет входные параметры для ручного запуска.
name: Trigger workflow_dispatch
on:
workflow_dispatch: # Это включает ручной запуск
inputs:
environment:
type: choice
options:
- dev
- staging
- production
default: staging
description: 'Target deployment environment'
timeout:
type: number
default: 60
description: 'Max time for deployment in seconds'
deploy:
type: boolean
default: true
description: 'To deploy'
deploy_version:
description: 'Application version to deploy'
required: true
default: '1.0.0'
jobs:
manual-trigger:
runs-on: ubuntu-latest
steps:
- name: Show Dispatch Inputs
run: |
echo "Trigger: ${{ gitverse.event_name }}"
echo "Triggered by: ${{ gitverse.actor }}"
echo "Environment: ${{ inputs.environment }}"
echo "Timeout: ${{ inputs.timeout }} seconds"
echo "Deploy: ${{ inputs.deploy }}"
echo "Deploy version: ${{ inputs.deploy_version }}"on.workflow_dispatch.inputs.<input_id>.required
Указывает, что входной параметр является обязательным.
on.workflow_dispatch.inputs.<input_id>.type
Указывает тип входного параметра.
env
Переменные окружения, используемые в workflow.
# Использование переменных окружения (env:) глобально и локально
name: Env Variables
on:
push:
branches:
- master
jobs:
env usage:
runs-on: ubuntu-latest
# Глобальные переменные окружения (для всей задачи)
env:
GLOBAL_VAR: "Привет из глобальной переменной"
steps:
# Локальная переменная окружения (только для этого шага)
- name: Print global + local env
env:
LOCAL_VAR: "Привет из локальной переменной"
run: |
echo "GLOBAL_VAR = $GLOBAL_VAR"
echo "LOCAL_VAR = $LOCAL_VAR"jobs
Секция, описывающая индивидуальные задания в workflow.
jobs.<job_id>
Идентификатор задания.
jobs:
my_first_job: # идентификатор задания
name: My first job
my_second_job: # идентификатор задания
name: My second job jobs.<job_id>.name
Имя задания, отображаемое в интерфейсе.
jobs.<job_id>.needs
Зависимости задания от других заданий.
# Обязательно выполнение зависимого задания
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]# Необязательное выполнение зависимого задания
jobs:
job1:
job2:
needs: job1
job3:
if: ${{ always() }}
needs: [job1, job2]jobs.<job_id>.if
Условие, при котором задание будет выполнено.
if: ${{ ! startsWith(gitverse.ref, 'refs/tags/') }}# Запуск только в определенном репозитории
name: example-workflow
on: [push]
jobs:
production-deploy:
if: gitverse.repository == 'actions/starter-workflows'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '14'
- run: npm install -g batsjobs.<job_id>.runs-on
Среда выполнения задания (метка для раннера).
runs-on: [self-hosted, x64]on:
workflow_dispatch:
inputs:
chosen-os:
required: true
type: choice
options:
- Ubuntu
- macOS
jobs:
test:
runs-on: [self-hosted, "${{ inputs.chosen-os }}"]
steps:
- run: echo Hello world!jobs.<job_id>.environment
Среда, в которой выполняется задание.
environment: staging_environmentenvironment:
name: production_environment
url: ${{ steps.step_id.outputs.url_output }}jobs.<job_id>.outputs
Выходные данные задания, используемые другими заданиями.
jobs:
job1:
runs-on: ubuntu-latest
# Привязка выходных данных шага к выходным данным задания
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=hello" >> "$GITVERSE_OUTPUT"
- id: step2
run: echo "test=world" >> "$GITVERSE_OUTPUT"
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- env:
OUTPUT1: ${{needs.job1.outputs.output1}}
OUTPUT2: ${{needs.job1.outputs.output2}}
run: echo "$OUTPUT1 $OUTPUT2"jobs:
job1:
runs-on: ubuntu-latest
outputs:
output_1: ${{ steps.gen_output.outputs.output_1 }}
output_2: ${{ steps.gen_output.outputs.output_2 }}
output_3: ${{ steps.gen_output.outputs.output_3 }}
strategy:
matrix:
version: [1, 2, 3]
steps:
- name: Generate output
id: gen_output
run: |
version="${{ matrix.version }}"
echo "output_${version}=${version}" >> "$GITVERSE_OUTPUT"
job2:
runs-on: ubuntu-latest
needs: [job1]
steps:
# Will show
# {
# "output_1": "1",
# "output_2": "2",
# "output_3": "3"
# }
- run: echo '${{ toJSON(needs.job1.outputs) }}'jobs.<job_id>.env
Переменные окружения, специфичные для задания.
jobs:
job1:
env:
FIRST_NAME: Namejobs.<job_id>.defaults
Стандартные настройки для задания.
jobs.<job_id>.defaults.run
Настройки по умолчанию для команд задания.
jobs.<job_id>.defaults.run.shell
Оболочка по умолчанию для команд задания.
jobs.<job_id>.defaults.run.working-directory
Рабочая директория по умолчанию для команд задания.
jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./scriptsjobs.<job_id>.steps
Шаги, которые выполняются в задании.
name: Знакомство с шагами
on: push
jobs:
my-job:
name: My Job
runs-on: ubuntu-latest
steps:
- name: Вывести приветствие
env:
MY_VAR: Привет! Меня зовут
FIRST_NAME: Name
LAST_NAME: Lastname
run: |
echo $MY_VAR $FIRST_NAME $LAST_NAME.jobs.<job_id>.steps[*].id
Идентификатор шага.
jobs.<job_id>.steps[*].if
Условие, при котором шаг будет выполнен.
if: ${{ ! startsWith(gitverse.ref, 'refs/tags/') }} ## Только если событие — запрос на слияние
steps:
- name: My first step
if: ${{ gitverse.event_name == 'pull_request' }}
run: echo This event is a pull request that had an assignee removed.steps:
- name: My first step
uses: repo-org/action-name@master
- name: My backup step # Запустится, только если предыдущий шаг содержит ошибку
if: ${{ failure() }}
uses: actions/heroku@1.0.0# Пример для ситуации, когда секрет не назначен
name: Run a step if a secret has been set
on: push
jobs:
my-jobname:
runs-on: ubuntu-latest
env:
super_secret: ${{ secrets.SuperSecret }}
steps:
- if: ${{ env.super_secret != '' }}
run: echo 'This step will only run if the secret has a value set.'
- if: ${{ env.super_secret == '' }}
run: echo 'This step will only run if the secret does not have a value set.'jobs.<job_id>.steps[*].name
Имя шага, отображаемое в интерфейсе.
jobs.<job_id>.steps[*].uses
Action, используемый в шаге.
steps:
# указание коммита
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3
# указание мажорной версии релиза
- uses: actions/checkout@v5
# указание на специфичный релиз
- uses: actions/checkout@v5.2.0
# указание ветки
- uses: actions/checkout@masterjobs:
my_first_job:
runs-on: ubuntu-latest
steps:
# Этот шаг делает копию вашего репо
- name: My first step - check out repository
uses: actions/checkout@v5
# указание пути до определенного action
- name: Use local hello-world-action
uses: ./.gitverse/actions/hello-world-actionjobs:
my_first_job:
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Python setup
uses: actions/setup-python@v6
with:
python-version: '3.13' jobs.<job_id>.steps[*].run
Команда, выполняемая в шаге.
# Однострочная команда
- name: Install Dependencies
run: npm install# Мультистрочные команды
- name: Clean install dependencies and build
run: |
npm ci
npm run buildjobs.<job_id>.steps[*].working-directory
Рабочая директория для шага.
- name: Clean temp directory
run: rm -rf *
working-directory: ./tempjobs.<job_id>.steps[*].with
Параметры, передаваемые action.
jobs:
my_first_job:
steps:
- name: My first step
uses: actions/hello_world@master
with:
first_name: Name
middle_name: Midle Name
last_name: Last namejobs.<job_id>.steps[*].with.args
Аргументы командной строки.
steps:
- name: Explain why this job ran
uses: repo-org/action-name@master
with:
entrypoint: /bin/echo
args: The ${{ gitverse.event_name }} event triggered this step.jobs.<job_id>.steps[*].with.entrypoint
Точка входа для выполнения команды.
steps:
- name: Run a custom command
uses: repo-org/action-name@master
with:
entrypoint: /a/different/executablejobs.<job_id>.steps[*].env
Переменные окружения для шага.
steps:
- name: My first action
env:
FIRST_NAME: Namejobs.<job_id>.steps[*].continue-on-error
Параметр, определяющий, продолжать ли выполнение при ошибке.
# Шаг с continue-on-error: true
name: Fail And Continue
on:
push:
branches:
- master
jobs:
Fails and Continue:
runs-on: ubuntu-latest
steps:
- name: Шаг первый
run: exit 1
continue-on-error: true
- name: Шаг второй
run: echo "Этот шаг выполнится, несмотря на ошибку выше"jobs.<job_id>.steps[*].timeout-minutes
Максимальная продолжительность выполнения шага (в минутах), по истечении которой процесс будет остановлен. Значение параметра timeout-minutes должно быть целым положительным числом, дробные значения недопустимы.
jobs.<job_id>.timeout-minutes
Время ожидания для всего задания. Значение таймаут по умолчанию:
- 15 минут для облачного раннера;
- 3 часа для локального раннера.
# Ограничение времени выполнения job через timeout-minutes
name: Timeout Job
on:
push:
branches:
- master
jobs:
example:
runs-on: ubuntu-latest
timeout-minutes: 1 # максимум 1 минута на выполнение job
steps:
- name: Long task
# Указано 50 секунд для зеленых тестов, но job выполняется не более 1 минуты
run: sleep 50jobs.<job_id>.strategy
Стратегия выполнения задания, например, матричное выполнение.
jobs.<job_id>.strategy.matrix
Параметры матрицы для стратегии. Матрица — способ запуска нескольких задач параллельно с различными комбинациями параметров.
Это мощный и гибкий инструмент для организации ваших CI/CD-процессов. Она позволяет значительно автоматизировать и оптимизировать выполнение заданий, особенно когда требуется тестирование или развертывание в различных окружениях или с разными версиями зависимостей.
Для задания матрицы в GitVerse, используйте ключевое слово matrix внутри блока strategy и runs-on: ${{ matrix.os }}. Внутри matrix можно указать параметры, которые будут использоваться для создания различных комбинаций.
В данном случае, матрица используется для запуска задач с разными версиями Node.js и операционными системами. Каждая комбинация параметров создает отдельную задачу, что позволяет проверить работоспособность проекта в различных окружениях.
jobs:
build:
strategy:
matrix:
node-version: [12, 14, 16] # Разные версии Node.js
# !TODO матричная сборка
os: [self-hosted, ubuntu-latest] # Разные операционные системы
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm testjobs:
example_matrix:
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
version: [10, 12, 14]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.version }}matrix:
os:
- ubuntu-latest
- macos
node:
- version: 14
- version: 20
env: NODE_OPTIONS=--openssl-legacy-provider- matrix.os: ubuntu-latest
matrix.node.version: 14
- matrix.os: ubuntu-latest
matrix.node.version: 20
matrix.node.env: NODE_OPTIONS=--openssl-legacy-provider
- matrix.os: macos
matrix.node.version: 14
- matrix.os: macos
matrix.node.version: 20
matrix.node.env: NODE_OPTIONS=--openssl-legacy-providerПодробнее см. раздел Матричные сборки.
jobs.<job_id>.strategy.matrix.include
Включает дополнительные параметры в матрицу.
jobs:
example_matrix:
strategy:
matrix:
os: [windows, ubuntu-latest]
node: [14, 16]
include:
- os: windows-latest
node: 16
npm: 6
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- if: ${{ matrix.npm }}
run: npm install -g npm@${{ matrix.npm }}
- run: npm --versionjobs:
example_matrix:
strategy:
matrix:
os: [macos, windows, ubuntu-latest]
version: [12, 14, 16]
include:
- os: windows-latest
version: 17jobs:
includes_only:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- site: "production"
datacenter: "site-a"
- site: "staging"
datacenter: "site-b"jobs.<job_id>.strategy.matrix.exclude
Исключает определенные параметры из матрицы.
jobs.<job_id>.strategy.fail-fast
Определяет, останавливать ли выполнение при первой неудаче.
jobs:
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: true
matrix:
version: [6, 7, 8]
experimental: [false]
include:
- version: 9
experimental: truejobs.<job_id>.strategy.max-parallel
Максимальное количество параллельных заданий.
jobs.<job_id>.continue-on-error
Продолжать выполнение задания при ошибке.
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
node: [13, 14]
os: [self-hosted, ubuntu-latest]
experimental: [false]
include:
- node: 15
os: ubuntu-latest
experimental: truejobs.<job_id>.container
Настройки контейнера для задания.
name: CI
on:
push:
branches: [ master ]
jobs:
container-test-job:
runs-on: ubuntu-latest
container:
image: node:18
env:
NODE_ENV: development
ports:
- 80
volumes:
- my_docker_volume:/volume_mount
options: --cpus 1
steps:
- name: Check for dockerenv file
run: (ls /.dockerenv && echo Found dockerenv) || (echo No dockerenv)jobs:
container-test-job:
runs-on: ubuntu-latest
container: node:18jobs.<job_id>.container.image
Образ контейнера, используемый для выполнения задания.
jobs.<job_id>.container.credentials
Учетные данные для доступа к образу контейнера.
container:
image: ghcr.io/owner/image
credentials:
username: ${{ gitverse.actor }}
password: ${{ secrets.gitverse_token }}jobs.<job_id>.container.env
Переменные окружения контейнера.
jobs.<job_id>.container.ports
Порты, открываемые контейнером.
jobs.<job_id>.container.volumes
Тома, монтируемые в контейнер.
volumes:
- my_docker_volume:/volume_mount
- /data/my_data
- /source/directory:/destination/directoryjobs.<job_id>.container.options
Дополнительные опции контейнера.
jobs.<job_id>.uses
Action, используемый в задании.
Info
Можно вызывать workflow из приватных репозиториев внутри одной организации.
jobs:
call-workflow-1-in-local-repo:
uses: repo-org/this-repo/.gitverse/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89
call-workflow-2-in-local-repo:
uses: ./.gitverse/workflows/workflow-2.yml
call-workflow-in-another-repo:
uses: repo-org/another-repo/.gitverse/workflows/workflow.yml@v1jobs.<job_id>.with
Параметры, передаваемые action.
jobs:
call-workflow:
uses: actions/starter-workflows/.gitverse/workflows/deploy_workflows/container-app.yaml@master
with:
username: userjobs.<job_id>.with.<input_id>
Конкретный параметр для действия.
jobs.<job_id>.secrets
Секреты, используемые в задании.
jobs:
call-workflow:
uses: actions/starter-workflows/.gitverse/workflows/deploy_workflows/container-app.yaml@master
secrets:
access-token: ${{ secrets.CLOUD_RU_PASSWORD }}jobs.<job_id>.secrets.inherit
Наследует ли секреты из более высокого уровня.
on:
workflow_dispatch:
jobs:
pass-secrets-to-workflow:
uses: ./.gitverse/workflows/called-workflow.yml
secrets: inheriton:
workflow_call:
jobs:
pass-secret-to-action:
runs-on: ubuntu-latest
steps:
- name: Use a repo or org secret from the calling workflow.
run: echo ${{ secrets.CALLING_WORKFLOW_SECRET }}jobs.<job_id>.secrets.<secret_id>
Конкретный секрет, используемый в задании.