# Создание действия контейнера Docker

В этом руководстве вы узнаете, как создать действие контейнера Docker.

## Введение

В этом руководстве вы узнаете об основных компонентах, необходимых для создания и использования упакованного действия контейнера Docker. Чтобы сосредоточиться в этом руководстве на компонентах, необходимых для упаковки действия, функциональные возможности кода действия будут минимальны. Действие печатает «Hello World» в логах или «Hello \[who-to-greet]», если вы дадите кастомное имя.

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

В локальных средствах выполнения должна использоваться операционная система Linux и должен быть установлен Docker для выполнения действий с контейнерами Docker. Дополнительные сведения о требованиях локальных средств выполнения см. в разделе [Справочник по локальным запускам](/ru/actions/reference/runners/self-hosted-runners#requirements-for-self-hosted-runner-machines).

> \[!WARNING]
> При создании рабочих процессов и действий следует всегда учитывать, может ли код выполнять ненадежные входные данные от возможных злоумышленников. Некоторые контексты следует считать непроверенными, так как злоумышленники могут вставить собственное вредоносное содержимое. Дополнительные сведения см. в разделе [Справочник по безопасному использованию](/ru/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks).

## Необходимые компоненты

* Необходимо создать репозиторий GitHub и клонировать его на рабочую станцию. Дополнительные сведения см. в разделе \[AUTOTITLE и [Создание репозитория](/ru/repositories/creating-and-managing-repositories/creating-a-new-repository)]\(/repositories/creating-and-managing-repositories/cloning-a-repository).
* Если используется Git LFS (Git Large File Storage — поддержка хранения больших файлов в Git)репозиторий, необходимо включить объекты в архивы репозитория. Дополнительные сведения см. в разделе [Управление объектами LFS Git в архивах репозитория](/ru/enterprise-cloud@latest/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/managing-git-lfs-objects-in-archives-of-your-repository).
* Вы можете найти полезное представление о GitHub Actionsпеременных среды и файловой системе контейнера Docker. Дополнительные сведения см. в разделе \[AUTOTITLE и [Хранение сведений в переменных](/ru/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables)]\(/actions/reference/runners/github-hosted-runners#docker-container-filesystem).

## Создание файла Dockerfile

В новом каталоге `hello-world-docker-action` создайте файл `Dockerfile`. Убедитесь, что имя файла имеет прописную букву (используйте прописную букву `D`, но не прописную букву `f`), если у вас возникли проблемы. Дополнительные сведения см. в разделе [Поддержка Dockerfile для GitHub Actions](/ru/actions/reference/workflows-and-actions/dockerfile-support).

**Dockerfile**

```dockerfile copy
# Container image that runs your code
FROM alpine:3.10

# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh

# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]
```

## Создание файла метаданных действия

Создайте новый файл `action.yml` в каталоге `hello-world-docker-action`. Дополнительные сведения см. в разделе [Справочник по синтаксису метаданных](/ru/actions/reference/workflows-and-actions/metadata-syntax).

**action.yml**

```yaml copy
# action.yml
name: 'Hello World'
description: 'Greet someone and record the time'
inputs:
  who-to-greet:  # id of input
    description: 'Who to greet'
    required: true
    default: 'World'
outputs:
  time: # id of output
    description: 'The time we greeted you'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.who-to-greet }}
```

Эти метаданные определяют один `who-to-greet` входной и один выходной `time` параметр. Чтобы передать входные данные в контейнер Docker, необходимо объявить входные данные с помощью `inputs` и передать их в ключевом слове `args`. Все, что вы включаете в контейнер, передается в контейнер `args`, но для лучшего обнаружения для пользователей вашего действия мы рекомендуем использовать входные данные.

GitHub будет создавать образ из вашего `Dockerfile`образа и выполнять команды в новом контейнере с помощью этого образа.

## Написание кода действия

Вы можете выбрать любой базовый образ Docker и, следовательно, любой язык для своего действия. В указанном ниже примере скрипта оболочки используется входная переменная `who-to-greet` для печати Hello \[who-to-greet] в файле журнала.

Затем скрипт получает текущее время и присваивает его выходной переменной, которую смогут использовать действия, выполняемые позже в рамках задания. Чтобы GitHub распознать выходные переменные, необходимо записать их в `$GITHUB_OUTPUT` файл среды: `echo "<output name>=<value>" >> $GITHUB_OUTPUT` Дополнительные сведения см. в разделе [Команды рабочего процесса для GitHub Actions](/ru/actions/reference/workflows-and-actions/workflow-commands#setting-an-output-parameter).

1. Создайте файл `entrypoint.sh` в новом каталоге `hello-world-docker-action`.

2. Добавьте в файл `entrypoint.sh` указанный ниже код.

**entrypoint.sh**

```shell copy
#!/bin/sh -l

echo "Hello $1"
time=$(date)
echo "time=$time" >> $GITHUB_OUTPUT

```

Если `entrypoint.sh` выполняется без ошибок, состояние действия имеет значение `success`. Вы также можете явно задать коды выхода в коде действия, чтобы предоставить состояние действия. Дополнительные сведения см. в разделе [Настройка кодов выхода для действий](/ru/actions/how-tos/create-and-publish-actions/set-exit-codes).

1. Сделайте исполняемый `entrypoint.sh` файл исполняемым файлом. Git предоставляет способ явного изменения режима разрешений файла, чтобы он не сбрасывал каждый раз, когда есть клон/вилка.

   ```shell copy
   git add entrypoint.sh
   git update-index --chmod=+x entrypoint.sh
   ```

2. При необходимости, чтобы проверить режим разрешений файла в индексе Git, выполните следующую команду.

   ```shell copy
   git ls-files --stage entrypoint.sh
   ```

   Выходные данные, такие как `100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       entrypoint.sh` означает, что файл имеет разрешение исполняемого файла. В этом примере `755` обозначает разрешение исполняемого файла.

## Создание файла README

Чтобы сообщить людям, как применить свое действие, можно создать файл README. Файл сведений наиболее полезен, если вы планируете опубликовать действие в открытом доступе, но может также применяться в качестве напоминания для себя или своей команды.

В каталоге `hello-world-docker-action` создайте файл `README.md` со следующими сведениями:

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

**README.md**

```markdown copy
# Hello world docker action

This action prints "Hello World" or "Hello" + the name of a person to greet to the log.

## Inputs

## `who-to-greet`

**Required** The name of the person to greet. Default `"World"`.

## Outputs

## `time`

The time we greeted you.

## Example usage

uses: actions/hello-world-docker-action@v2
with:
  who-to-greet: 'Mona the Octocat'
```

## Фиксация, тег и отправка действия

В терминале зафиксируйте файлы `action.yml`, `entrypoint.sh`, `Dockerfile` и `README.md`.

Рекомендуется также добавить тег версии для выпусков действия. Дополнительные сведения о настройке версий см. в разделе [Управление пользовательскими действиями](/ru/actions/how-tos/create-and-publish-actions/manage-custom-actions#using-release-management-for-actions).

```shell copy
git add action.yml entrypoint.sh Dockerfile README.md
git commit -m "My first action is ready"
git tag -a -m "My first action release" v1
git push --follow-tags
```

## Тестирование действия в рабочем процессе

Теперь вы готовы протестировать действие в рабочем процессе.

* Если действие находится в частном репозитории, вы можете управлять доступом к нему. Дополнительные сведения см. в разделе [Управление настройками GitHub Actions для репозитория](/ru/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-access-to-components-in-a-private-repository).
* Если действие находится во внутреннем репозитории, действие может использоваться только в рабочих процессах в одном репозитории.
* Общедоступные действия могут использоваться рабочими процессами в любом репозитории.

### Пример. Использование общедоступного действия

В указанном ниже коде рабочего процесса используется готовое действие *hello world* в общедоступном репозитории [`actions/hello-world-docker-action`](https://github.com/actions/hello-world-docker-action). Скопируйте указанный ниже пример кода рабочего процесса в файл `.github/workflows/main.yml`, но замените `actions/hello-world-docker-action` именем репозитория и действия. Вы также можете заменить входное поле `who-to-greet` на свое имя.
Общедоступные действия можно использовать, даже если они не публикуются GitHub Marketplace. Дополнительные сведения см. в разделе [Публикация действий в GitHub Marketplace](/ru/actions/how-tos/create-and-publish-actions/publish-in-github-marketplace#publishing-an-action).

**.github/workflows/main.yml**

```yaml copy
on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      - name: Hello world action step
        id: hello
        uses: actions/hello-world-docker-action@v2
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"
```

### Пример использования частного действия

Скопируйте указанный ниже пример кода рабочего процесса в файл `.github/workflows/main.yml` в репозитории действия. Вы также можете заменить входное поле `who-to-greet` на свое имя.
Это частное действие не может быть опубликовано GitHub Marketplaceи может использоваться только в этом репозитории.

**.github/workflows/main.yml**

```yaml copy
on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      # To use this repository's private action,
      # you must check out the repository
      - name: Checkout
        uses: actions/checkout@v6
      - name: Hello world action step
        uses: ./ # Uses an action in the root directory
        id: hello
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"
```

В репозитории перейдите на вкладку **Действия** и выберите последний запуск рабочего процесса. В разделе **Задания** или в графе визуализации щелкните **Задание для отображения приветствия**.

Нажмите кнопку **"Hello world action step**", и вы увидите "Hello Mona the Octocat" или имя, которое вы использовали для `who-to-greet` ввода, напечатанного в журнале. Чтобы просмотреть метку времени, нажмите кнопку **"Получить время** вывода".

## Доступ к файлам, созданным действием контейнера

При выполнении действия контейнера он автоматически сопоставляет рабочий каталог по умолчанию (`GITHUB_WORKSPACE`) в средстве выполнения с `/github/workspace` каталогом в контейнере. Все файлы, добавленные в этот каталог в контейнере, будут доступны для всех последующих шагов в том же задании. Например, если у вас есть действие контейнера, которое создает проект, и вы хотите отправить выходные данные сборки в качестве артефакта, можно выполнить следующие действия.

**workflow\.yml**

```yaml copy
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      # Output build artifacts to /github/workspace on the container.
      - name: Containerized Build
        uses: ./.github/actions/my-container-action

      - name: Upload Build Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: workspace_artifacts
          path: ${{ github.workspace }}
```

Дополнительные сведения о передаче выходных данных сборки в качестве артефакта см. в разделе [Хранение и предоставление общего доступа к данным с артефактами рабочего процесса](/ru/actions/tutorials/store-and-share-data).

## Примеры действий контейнера Docker в GitHub.com

Вы можете найти множество примеров действий контейнера Docker в GitHub.com.

* [github/issue-metrics](https://github.com/github/issue-metrics)
* [microsoft/infersharpaction](https://github.com/microsoft/infersharpaction)
* [Microsoft/ps-docs](https://github.com/microsoft/ps-docs)