# Создание действия JavaScript

В этом руководстве вы узнаете, как создать действие JavaScript с помощью набора средств действий.

## Введение

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

Для ускорения разработки в этом руководстве применяется модуль Node.js из набора средств GitHub Actions. Дополнительные сведения см. в репозитории [actions/toolkit](https://github.com/actions/toolkit).

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

Чтобы обеспечить совместимость действий JavaScript со всеми средствами выполнения, размещенными в GitHub (Ubuntu, Windows и macOS), упакованный код JavaScript должен быть чистым JavaScript без зависимостей от других двоичных файлов. Действия JavaScript запускаются непосредственно в средстве выполнения и используют двоичные файлы, которые уже существуют в образе средства выполнения тестов.

> \[!WARNING]
> При создании рабочих процессов и действий следует всегда учитывать, может ли код выполнять ненадежные входные данные от возможных злоумышленников. Некоторые контексты следует считать непроверенными, так как злоумышленники могут вставить собственное вредоносное содержимое. Дополнительные сведения см. в разделе [Справочник по безопасному использованию](/ru/actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections).

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

Перед началом работы необходимо скачать Node.js и создать общедоступный репозиторий GitHub.

1. Скачайте и установите Node.js 20.x, включающую npm.

   <https://nodejs.org/en/download/>

2. Создайте новый общедоступный репозиторий на GitHub и вызовите его "hello-world-javascript-action". Дополнительные сведения см. в разделе [Создание репозитория](/ru/repositories/creating-and-managing-repositories/creating-a-new-repository).

3. Клонируйте репозиторий на ваш компьютер. Дополнительные сведения см. в разделе [Клонирование репозитория](/ru/repositories/creating-and-managing-repositories/cloning-a-repository).

4. В окне терминала перейдите в новый репозиторий.

   ```shell copy
   cd hello-world-javascript-action
   ```

5. В окне терминала инициализируйте каталог с помощью npm, чтобы создать файл `package.json`.

   ```shell copy
   npm init -y
   ```

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

Создайте в каталоге `action.yml` файл с именем `hello-world-javascript-action`, содержащий приведенный ниже код. Дополнительные сведения см. в разделе [Справочник по синтаксису метаданных](/ru/actions/creating-actions/metadata-syntax-for-github-actions).

```yaml copy
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: node20
  main: dist/index.js
```

В этом файле определяются входной атрибут `who-to-greet` и выходной атрибут `time`. В нем также указывается способ запуска этого действия JavaScript средством выполнения.

## Добавление пакетов из набора средств actions

Набор средств actions — это коллекция пакетов Node.js, которые позволяют быстро и согласованно создавать действия JavaScript.

Пакет [`@actions/core`](https://github.com/actions/toolkit/tree/main/packages/core) из набора средств предоставляет интерфейс для команд рабочего процесса, входных и выходных переменных, состояний выхода и сообщений отладки.

Инструментарий также предлагает пакет [`@actions/github`](https://github.com/actions/toolkit/tree/main/packages/github), который возвращает аутентифицированный клиент Octokit REST и доступ к GitHub Actions контекстам.

Набор средств не ограничивается пакетами `core` и `github`. Дополнительные сведения см. в репозитории [actions/toolkit](https://github.com/actions/toolkit).

В окне терминала установите пакеты `core` и `github` из набора средств actions.

```shell copy
npm install @actions/core @actions/github
```

Теперь вы увидите `node_modules` каталог и `package-lock.json` файл, отслеживающий все установленные зависимости и их версии. Вы не должны зафиксировать каталог в `node_modules` репозитории.

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

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

GitHub Actions предоставляет контекстную информацию о событии webhook, ссылках на Git, рабочем процессе, действии и человеке, который запустил этот рабочий процесс. Для доступа к сведениям о контексте можно использовать пакет `github`. Вы напишете действие, которое будет записывать полезные данные события веб-перехватчика в журнал.

Добавьте файл с именем `src/index.js`, содержащий приведенный ниже код.

```javascript copy
import * as core from "@actions/core";
import * as github from "@actions/github";

try {
  // `who-to-greet` input defined in action metadata file
  const nameToGreet = core.getInput("who-to-greet");
  core.info(`Hello ${nameToGreet}!`);

  // Get the current time and set it as an output variable
  const time = new Date().toTimeString();
  core.setOutput("time", time);

  // Get the JSON webhook payload for the event that triggered the workflow
  const payload = JSON.stringify(github.context.payload, undefined, 2);
  core.info(`The event payload: ${payload}`);
} catch (error) {
  core.setFailed(error.message);
}
```

Если в приведенном выше примере `index.js` возникает ошибка, `core.setFailed(error.message);` использует пакет [`@actions/core`](https://github.com/actions/toolkit/tree/main/packages/core) из набора средств actions для регистрации сообщения и задания кода выхода "сбой". Дополнительные сведения см. в разделе [Настройка кодов выхода для действий](/ru/actions/creating-actions/setting-exit-codes-for-actions).

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

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

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

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

````markdown copy
# Hello world JavaScript 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

```yaml
uses: actions/hello-world-javascript-action@e76147da8e5c81eaf017dede5645551d4b94427b
with:
  who-to-greet: Mona the Octocat
```
````

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

GitHub загружает каждое действие в рабочем процессе во время выполнения и выполняет его как полный пакет кода, прежде чем использовать команды рабочих процессов, как `run` взаимодействовать с компьютером runner. Это означает, что необходимо включить все зависимости пакетов, необходимые для выполнения кода JavaScript. Например, это действие использует `@actions/core` и `@actions/github` пакеты.

Возврат каталога `node_modules` может привести к проблемам. В качестве альтернативы можно использовать такие средства, как `rollup.js`[](https://github.com/rollup/rollup)или объединить код и зависимости в один файл для распространения.

1. Установите `rollup` и его подключаемые модули, выполнив эту команду в терминале.

   `npm install --save-dev rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve`

2. Создайте новый файл, который вызывается `rollup.config.js` в корневом каталоге репозитория, с помощью следующего кода.

   ```javascript copy
   import commonjs from "@rollup/plugin-commonjs";
   import { nodeResolve } from "@rollup/plugin-node-resolve";

   const config = {
     input: "src/index.js",
     output: {
       esModule: true,
       file: "dist/index.js",
       format: "es",
       sourcemap: true,
     },
     plugins: [commonjs(), nodeResolve({ preferBuiltins: true })],
   };

   export default config;
   ```

3. Скомпилируйте файл `dist/index.js`.

   `rollup --config rollup.config.js`

   Вы увидите новый `dist/index.js` файл с кодом и любыми зависимостями.

4. В терминале зафиксируйте обновления.

   ```shell copy
   git add src/index.js dist/index.js rollup.config.js package.json package-lock.json README.md action.yml
   git commit -m "Initial commit of my first action"
   git tag -a -m "My first action release" v1.1
   git push --follow-tags
   ```

При фиксации и отправке кода обновленный репозиторий должен выглядеть следующим образом:

```text
hello-world-javascript-action/
├── action.yml
├── dist/
│   └── index.js
├── package.json
├── package-lock.json
├── README.md
├── rollup.config.js
└── src/
    └── index.js
```

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

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

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

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

В этом примере показано, как можно запустить новое общедоступное действие из внешнего репозитория.

Скопируйте приведенный ниже код YAML в новый файл по пути `.github/workflows/main.yml` и измените строку `uses: octocat/hello-world-javascript-action@1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b`, указав свое имя пользователя и имя созданного ранее общедоступного репозитория. Вы также можете заменить входное поле `who-to-greet` на свое имя.

```yaml copy
on:
  push:
    branches:
      - main

jobs:
  hello_world_job:
    name: A job to say hello
    runs-on: ubuntu-latest

    steps:
      - name: Hello world action step
        id: hello
        uses: octocat/hello-world-javascript-action@1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
        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-javascript-action` из общедоступного репозитория, а затем запускает его.

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

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

```yaml copy
on:
  push:
    branches:
      - main

jobs:
  hello_world_job:
    name: A job to say hello
    runs-on: ubuntu-latest

    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` ввода, напечатанного в журнале. Чтобы просмотреть метку времени, нажмите кнопку **"Получить время** вывода".

## Репозитории шаблонов для создания действий JavaScript

GitHub предоставляет репозитории шаблонов для создания действий JavaScript и TypeScript. С помощью этих шаблонов можно быстро приступить к созданию нового действия, включающего тесты, подкладку и другие рекомендуемые методики.

* [
  `javascript-action` репозиторий шаблонов](https://github.com/actions/javascript-action)
* [
  `typescript-action` репозиторий шаблонов](https://github.com/actions/typescript-action)

## Пример действий JavaScript для GitHub.com

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

* [DevExpress/testcafe-action](https://github.com/DevExpress/testcafe-action)
* [duckduckgo/privacy-configuration](https://github.com/duckduckgo/privacy-configuration)