Структура workflow, настройка jobs и steps, передача данных между шагами.
Понимание структуры workflow — основа эффективной настройки CI/CD в GitHub Actions. Изучите иерархию компонентов и способы передачи данных между ними.
Workflow
├── Job 1 (runs-on: ubuntu-latest)
│ ├── Step 1 (uses: actions/checkout@v4)
│ ├── Step 2 (run: npm install)
│ └── Step 3 (run: npm test)
├── Job 2 (runs-on: ubuntu-latest)
│ ├── Step 1 (uses: actions/checkout@v4)
│ └── Step 2 (run: npm run build)
Ключевые принципы:
Базовая структура YAML-файла workflow:
name: CI/CD Pipeline
on:
push:
branches: [main]
jobs:
job_id:
runs-on: ubuntu-latest
steps:
- name: Step name
uses: action@version
- run: shell command| Поле | Описание |
|---|---|
name | Человекочитаемое название workflow (отображается в UI) |
on | Триггеры для запуска workflow |
jobs | Список jobs для выполнения |
name: Full CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run buildjobs:
build:
runs-on: ubuntu-latest
name: Build Application
timeout-minutes: 30
continue-on-error: false
steps:
- run: echo "Building..."| Поле | Тип | Описание |
|---|---|---|
runs-on | string | Тип runner для выполнения job |
name | string | Человекочитаемое название (для UI) |
needs | array/string | Зависимости от других jobs |
if | string | Условие выполнения job |
timeout-minutes | number | Максимальное время выполнения |
continue-on-error | boolean | Продолжать ли workflow при ошибке |
strategy | object | Matrix strategy для параллелизации |
outputs | object | Выходные значения job |
environment | string/object | Окружение для деплоя |
concurrency | object/group | Ограничение параллельных запусков |
Jobs выполняются параллельно по умолчанию. Для последовательного выполнения используйте needs:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint # Запустится после успешного lint
steps:
- run: npm test
deploy:
runs-on: ubuntu-latest
needs: [lint, test] # Запустится после обоих jobs
steps:
- run: ./deploy.shСтатусы job:
success — job завершился успешноfailure — job завершился с ошибкойcancelled — job был отменёнskipped — job был пропущен1. Запуск команды (run):
steps:
- name: Install dependencies
run: npm ci
- name: Run tests
run: |
echo "Running tests..."
npm test
echo "Tests complete"2. Использование action (uses):
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'3. Именованный step для outputs:
steps:
- name: Get version
id: get_version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT| Поле | Тип | Описание |
|---|---|---|
name | string | Человекочитаемое название step |
id | string | Уникальный ID для ссылок в expressions |
uses | string | Action для использования |
run | string | Shell-команда для выполнения |
with | object | Входные параметры для action |
env | object | Переменные окружения для step |
if | string | Условие выполнения step |
continue-on-error | boolean | Продолжать при ошибке |
timeout-minutes | number | Таймаут step |
working-directory | string | Рабочая директория |
steps:
- name: Build and test
run: |
npm ci
npm run build
npm test
working-directory: ./frontendsteps:
- name: Deploy to production
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: ./deploy.sh
- name: Send notification on failure
if: failure()
run: ./notify-slack.sh
- name: Always run cleanup
if: always()
run: ./cleanup.shФункции условий:
success() — true, если предыдущие steps успешны (по умолчанию)failure() — true, если предыдущий step неудаченalways() — true всегдаcancelled() — true, если workflow отменёнskipped() — true, если workflow пропущенjobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set version
id: set_version
run: echo "VERSION=1.2.3" >> $GITHUB_ENV
- name: Use version
run: echo "Building version $VERSION"Важно: Переменные, записанные в $GITHUB_ENV, доступны только в последующих steps того же job.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get version
id: get_version
run: |
echo "version=$(cat package.json | jq -r .version)" >> $GITHUB_OUTPUT
echo "build_number=${{ github.run_number }}" >> $GITHUB_OUTPUT
- name: Use outputs
run: |
echo "Version: ${{ steps.get_version.outputs.version }}"
echo "Build: ${{ steps.get_version.outputs.build_number }}"steps:
- name: Generate report
run: npm test -- --reporter=json > test-results.json
- name: Process report
run: node process-results.js test-results.jsonjobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
artifact_name: ${{ steps.build.outputs.artifact_name }}
steps:
- name: Get version
id: get_version
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
- name: Build
id: build
run: echo "artifact_name=app-1.2.3" >> $GITHUB_OUTPUT
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy
run: |
echo "Deploying version ${{ needs.build.outputs.version }}"
echo "Artifact: ${{ needs.build.outputs.artifact_name }}"jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 5
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ./deploy.shjobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
notify:
runs-on: ubuntu-latest
needs: test
continue-on-error: true
steps:
- run: ./notify-slack.shjobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
runs-on: ubuntu-latest
needs: test
if: success() # Только если test успешен
steps:
- run: ./deploy.sh
cleanup:
runs-on: ubuntu-latest
needs: test
if: always() # Всегда, независимо от статуса test
steps:
- run: ./cleanup.shjobs:
long-running:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- run: ./long-process.shОграничивает количество параллельных запусков workflow:
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: ./deploy.shПоведение:
name: Full CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
build:
runs-on: ubuntu-latest
needs: test
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Get version
id: version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
deploy-staging:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment: staging
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ./deploy.sh staging
deploy-production:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ./deploy.sh production
notify:
runs-on: ubuntu-latest
needs: [deploy-staging, deploy-production]
if: always()
continue-on-error: true
steps:
- run: ./notify-slack.shneeds)$GITHUB_ENV, $GITHUB_OUTPUT, файлыoutputs job и артефактыif с функциями success(), failure(), always()timeout-minutesВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.