---
metadata:
  - name: generator
    content: Diplodoc Platform v5.57.3
alternate:
  - https://sourcecraft.dev/portal/docs/en/sourcecraft/operations/ci-cd.md
  - https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/ci-cd.md
  - href: https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/ci-cd.md
    type: text/markdown
    title: Markdown version
  - href: https://sourcecraft.dev/portal/docs/ru/llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://sourcecraft.dev/portal/docs/ru/llms.txt

# Настроить CI/CD в репозитории SourceCraft

<!-- source: ru/_includes/sourcecraft/configuration-tip.md -->
{% note tip %}

Настройка и просмотр конфигураций репозитория доступны в интерфейсе SourceCraft в разделе ![image](../../_assets/console-icons/gear.svg) **Настройки репозитория** в секции ![image](../../_assets/console-icons/nut-hex.svg) **Конфигурации**. Подробнее в инструкции [Настроить конфигурации репозитория в виде кода](https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/configuration-edit.md).

{% endnote %}
<!-- endsource: ru/_includes/sourcecraft/configuration-tip.md -->

В SourceCraft встроен механизм для работы с [CI/CD-процессами](https://sourcecraft.dev/portal/docs/ru/sourcecraft/concepts/ci-cd.md).

<!-- source: ru/_includes/sourcecraft/ci-cd/config-file-description.md -->
Конфигурация CI/CD задается для конкретного репозитория и хранится в файле `.sourcecraft/ci.yaml`.

Общий вид конфигурационного файла `.sourcecraft/ci.yaml`:

```yaml
on:
  pull_request:
    - workflows: [<список_рабочих_процессов>]
      filter:
        source_branches: [<список_исходных_веток>]
        target_branches: [<список_целевых_веток>]
        paths: [<список_путей>]

  push:
    - workflows: [<список_рабочих_процессов>]
      filter:
        branches: [<список_веток>]
        paths: [<список_путей>]
    - workflows: [<список_рабочих_процессов>]
      filter:
        tags: [<список_тегов>]

  schedule:
    - workflows: [<список_рабочих_процессов>]
      interval: <интервал_запуска_в_часах_или_минутах>
      description: <произвольное_описание>
    - workflows: [<список_рабочих_процессов>]
      cron: "<cron-выражение>"
      description: <произвольное_описание>

workflows:
  <имя_рабочего_процесса>:

    tasks:
      - name: <имя_задания>
        
        cubes:
          - name: <имя_кубика>
            image: <путь_к_Docker-образу>
            script:
              - <выполняемый_скрипт>
...
```

Конфигурация может включать в себя следующие элементы:
* [События-триггеры](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/on.md) (блок `on`).
* [Рабочие процессы](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/workflows.md) (блок `workflows`).
* [Задания](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/tasks.md) (блок `tasks`).
* [Кубики](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/cubes.md) (блок `cubes`).
* [Сервисные подключения](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/tokens.md) (блок `tokens`).
* [Переменные окружения](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/env.md) (блок `env`).

{% note tip %}

Для файла `.sourcecraft/ci.yaml` поддерживаются вывод структуры файла, поиск деклараций и мест использования элементов. Подробнее на странице [Навигация и поиск по коду в SourceCraft](https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/code-navigation.md).

{% endnote %}

Вы можете использовать вложенную структуру для элементов конфигурации или разметить их в виде отдельных блоков.

{% cut "Пример конфигурации CI/CD в виде отдельных блоков" %}

```yaml
on:
  pull_request:
    - workflows: my-test-workflow
      filter:
        source_branches: ["**", "!test**"]
        target_branches: "main"

workflows:
  my-test-workflow:
    tasks:
      - my-test-task

tasks:
  - name: my-test-task
    cubes:
      - name: my-test-cube
        uses: hello-cube

cubes:
  - name: hello-cube
    script:
      - echo "Hello, world!"
```

{% endcut %}

В конфигурационном файле поддерживается использование [секретов](https://sourcecraft.dev/portal/docs/ru/sourcecraft/concepts/index.md#secrets). Подробнее в разделе [Использовать значение секрета в CI/CD](https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/secrets.md#use-secret-in-ci-cd).
<!-- endsource: ru/_includes/sourcecraft/ci-cd/config-file-description.md -->

CI/CD-процессы запускаются событиями-триггерами. Такими событиями могут быть отправка изменений в ветку удаленного репозитория (`push`), создание предложения изменений (`pull_request`) или запуск по расписанию (`schedule`).

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

Описание элементов конфигурации в [справочнике CI/CD](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/index.md).

Вы можете настроить CI/CD [при создании репозитория](#when-creating) или в [уже имеющемся](#existing).

## Настроить CI/CD при создании репозитория {#when-creating}

1. Откройте [главную страницу](https://sourcecraft.dev) SourceCraft.
1. На панели слева нажмите ![image](../../_assets/console-icons/plus.svg) **Создать репозиторий**.
1. В открывшемся окне задайте параметры репозитория.
1. В блоке **Настройки** выберите **Добавить шаблон cicd**.
1. В выпадающем списке **YAML** выберите шаблон конфигурации CI/CD:
    * `Docker`;
    * `HelloWorld`;
    * `Java`;
    * `NodeJS`;
    * `Python`.

    Содержимое шаблонов в подразделе [Примеры](#examples).

1. Нажмите **Создать репозиторий**.

    В корне созданного репозитория будет размещен файл `.sourcecraft/ci.yaml` с шаблоном конфигурации CI/CD.

## Настроить CI/CD в уже имеющемся репозитории {#existing}

1. Склонируйте репозиторий:

    <!-- source: ru/_includes/sourcecraft/clone-repo-workflow.md -->
    1. [Установите Git](https://git-scm.com/downloads).
    1. Откройте [главную страницу](https://sourcecraft.dev) SourceCraft.
    1. На вкладке ![image](../../_assets/console-icons/house.svg) **Домой** в секции ![image](../../_assets/console-icons/layout-tabs.svg) **Ваша мастерская** перейдите в раздел ![image](../../_assets/console-icons/archive.svg) **Репозитории** и выберите репозиторий.

        Также вы можете открыть любой публичный репозиторий.

    1. На странице репозитория в правом верхнем углу нажмите кнопку ![image](../../_assets/console-icons/chevron-down-wide.svg) **Клонировать**.
    1. Из поля **HTTPS** или **SSH** скопируйте ![image](../../_assets/console-icons/copy.svg) ссылку для клонирования репозитория.

        В зависимости от протокола подключения для клонирования используются разные домены:

        #|
        || **Протокол** | **Домен** | **Ссылка для клонирования** ||
        || HTTPS | `git.sourcecraft.dev` | `https://git@git.sourcecraft.dev/<слаг_организации>/<слаг_репозитория>.git` ||
        || SSH | `ssh.sourcecraft.dev` | `ssh://ssh.sourcecraft.dev/<слаг_организации>/<слаг_репозитория>.git` ||
        |#

    1. В терминале выполните команду:

        ```bash
        git clone <ссылка_для_клонирования_репозитория>
        ```

        {% cut "Пример команды для клонирования репозитория с документацией SourceCraft" %}

        ```bash
        git clone https://git@git.sourcecraft.dev/sourcecraft/documentation.git
        ```

        {% endcut %}

        <!-- source: ru/_includes/sourcecraft/private-repo-clone-note.md -->
        {% note warning %}

        Чтобы склонировать [приватный или внутренний репозиторий](https://sourcecraft.dev/portal/docs/ru/sourcecraft/concepts/index.md#repos), аутентифицируйтесь с помощью [персонального токена (PAT)](https://sourcecraft.dev/portal/docs/ru/sourcecraft/security/pat.md) или [SSH-ключа](https://sourcecraft.dev/portal/docs/ru/sourcecraft/security/ssh.md).

        {% endnote %}
        <!-- endsource: ru/_includes/sourcecraft/private-repo-clone-note.md -->

    1. Перейдите в склонированный репозиторий:
        
        ```bash
        cd <имя_репозитория>
        ```
    <!-- endsource: ru/_includes/sourcecraft/clone-repo-workflow.md -->

1. Сформируйте файл конфигурации CI/CD `.sourcecraft/ci.yaml` согласно описанию в [справочнике CI/CD](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/index.md) или воспользуйтесь шаблонами из подраздела [Примеры](#examples).

1. Добавьте файл конфигурации CI/CD в индекс `git`, сделайте коммит и отправьте изменения в ветку `main`:

    ```bash
    git add .sourcecraft/ci.yaml
    git commit -m "Added CI/CD configuration"
    git push -u origin main
    ```

## Проверить выполнение CI/CD-процесса {#check-ci-cd} 

1. В зависимости от настроек, указанных в `.sourcecraft/ci.yaml`, выполните событие-триггер.
1. Проверьте выполнение CI/CD-процесса:

    <!-- source: ru/_includes/sourcecraft/ci-cd/ui-overview.md -->
    1. На странице репозитория в разделе ![image](../../_assets/console-icons/code.svg) **Код** перейдите в секцию ![image](../../_assets/console-icons/arrows-3-rotate-right.svg) **CI/CD**.
    1. Выберите запущенный рабочий процесс (workflow).
    1. На открывшейся странице будут отображены все задания (tasks) рабочего процесса, шаги задания — кубики (cubes), а также статусы и результаты выполнения.
    <!-- endsource: ru/_includes/sourcecraft/ci-cd/ui-overview.md -->

## Примеры {#examples}

{% list tabs %}
  
  Откройте файл config.json. В нем уже задана базовая конфигурация ВМ, но вы можете указать собственные параметры:

- Hello World

  ```yaml
  # Это базовый рабочий процесс (workflow), который 
  # поможет вам начать работу с SourceCraft CI/CD

  # Настройка события-триггера для запуска рабочего процесса
  on:
    # Запуск рабочего процесса по отправке изменений в ветку main
    # удаленного репозитория, или когда создается предложение изменений в ветку main
    pull_request:
      - workflows: [sample-workflow]
        filter:
          source_branches: ["**", "!test**"]
          target_branches: "main"

    push:
      - workflows: [sample-workflow]
        filter:
          branches: ["main"]

  workflows:
    sample-workflow:
      tasks:
        - name: sample-task
        
          cubes:
            # Запуск набора команд 
            - name: sample-cube1
              image: docker.io/library/node
              script:
                - echo Hello, world!
             
            - name: sample-cube2
              script:
                - echo Add other cubes to build,
                - echo test, and deploy your project.
  ```

- Docker

  ```yaml
  on:
    push:
      - workflows: build-workflow 
        filter: 
          branches: ["main"]

  workflows:
    build-workflow:
      tasks:
        - build-task

  tasks:
    - name: build-task
      env:
          IMAGE_URI: dockerhub_account/hello-world
      cubes:
        - name: docker-build
          script:
            - docker build . --file Dockerfile --tag $IMAGE_URI:$(date +%s)
        # Опционально: отправка Docker-образа в реестр
        # Передайте в кубик данные для аутентификации в реестре,
        # например в Docker Hub или Yandex Container Registry
        # - name: push-dockerhub
        #   env:
        #     USER: username
        #     PAT: personal_access_token
        #   script:
        #     - echo $PAT | docker login --username $USER --password-stdin
        #     - docker push $IMAGE_URI
  ```

  Чтобы протестировать CI\CD-процесс, отправьте в ветку `main` коммит с файлом `Dockerfile`:

  ```dockerfile
  FROM alpine  
  CMD ["echo", "Hello World!!"]
  ```

- Python

  ```yaml
  on:
    push:
      - workflows: [sample-workflow]
        filter:
          branches: ["main"]

  workflows:
    sample-workflow:
      tasks:
        - name: sample-task
          cubes:
            - name: sample-cube1
              image: docker.io/library/python
              script:
                - python -m pip install --upgrade pip
                - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
  ```

  Добавьте в файл `.gitignore` данные, специфичные для тестирования приложений на Python.

  {% cut "Пример .gitignore" %}

  <!-- source: ru/_includes/sourcecraft/ci-cd/python-gitignore.md -->
  ```text
  # Byte-compiled / optimized / DLL files
  __pycache__/
  *.py[cod]
  *$py.class

  # C extensions
  *.so

  # Distribution / packaging
  .Python
  build/
  develop-eggs/
  dist/
  downloads/
  eggs/
  .eggs/
  lib/
  lib64/
  parts/
  sdist/
  var/
  wheels/
  share/python-wheels/
  *.egg-info/
  .installed.cfg
  *.egg
  MANIFEST

  # PyInstaller
  #  Usually these files are written by a python script from a template
  #  before PyInstaller builds the exe, so as to inject date/other infos into it.
  *.manifest
  *.spec

  # Installer logs
  pip-log.txt
  pip-delete-this-directory.txt

  # Unit test / coverage reports
  htmlcov/
  .tox/
  .nox/
  .coverage
  .coverage.*
  .cache
  nosetests.xml
  coverage.xml
  *.cover
  *.py,cover
  .hypothesis/
  .pytest_cache/
  cover/

  # Translations
  *.mo
  *.pot

  # Django stuff:
  *.log
  local_settings.py
  db.sqlite3
  db.sqlite3-journal

  # Flask stuff:
  instance/
  .webassets-cache

  # Scrapy stuff:
  .scrapy

  # Sphinx documentation
  docs/_build/

  # PyBuilder
  .pybuilder/
  target/

  # Jupyter Notebook
  .ipynb_checkpoints

  # IPython
  profile_default/
  ipython_config.py

  # pyenv
  #   For a library or package, you might want to ignore these files since the code is
  #   intended to run in multiple environments; otherwise, check them in:
  # .python-version

  # pipenv
  #   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
  #   However, in case of collaboration, if having platform-specific dependencies or dependencies
  #   having no cross-platform support, pipenv may install dependencies that don't work, or not
  #   install all needed dependencies.
  #Pipfile.lock

  # UV
  #   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
  #   This is especially recommended for binary packages to ensure reproducibility, and is more
  #   commonly ignored for libraries.
  #uv.lock

  # poetry
  #   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
  #   This is especially recommended for binary packages to ensure reproducibility, and is more
  #   commonly ignored for libraries.
  #   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
  #poetry.lock

  # pdm
  #   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
  #pdm.lock
  #   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
  #   in version control.
  #   https://pdm.fming.dev/latest/usage/project/#working-with-version-control
  .pdm.toml
  .pdm-python
  .pdm-build/

  # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
  __pypackages__/

  # Celery stuff
  celerybeat-schedule
  celerybeat.pid

  # SageMath parsed files
  *.sage.py

  # Environments
  .env
  .venv
  env/
  venv/
  ENV/
  env.bak/
  venv.bak/

  # Spyder project settings
  .spyderproject
  .spyproject

  # Rope project settings
  .ropeproject

  # mkdocs documentation
  /site

  # mypy
  .mypy_cache/
  .dmypy.json
  dmypy.json

  # Pyre type checker
  .pyre/

  # pytype static type analyzer
  .pytype/

  # Cython debug symbols
  cython_debug/

  # PyCharm
  #  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
  #  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
  #  and can be added to the global gitignore or merged into this file.  For a more nuclear
  #  option (not recommended) you can uncomment the following to ignore the entire idea folder.
  #.idea/

  # PyPI configuration file
  .pypirc
  ```
  <!-- endsource: ru/_includes/sourcecraft/ci-cd/python-gitignore.md -->

  {% endcut %}

  Чтобы протестировать CI\CD-процесс, отправьте в ветку `main` коммит с файлом `main.py`:

  ```python
  print('Hello SourceCraft')
  print('Hello SourceCraft')

  for i in range(10):
      print(i)

  # input 
  hi = input()
  print(hi)
  ```

- Node.js

  ```yaml
  on:
    push:
      - workflows: build-workflow 
        filter: 
          branches: ["main"]

  workflows:
    build-workflow:
      tasks:
        - build-task

  tasks:
    - name: build-task
      cubes:
        - name: build-npm
          image: docker.io/library/node
          script:
            - npm ci
            - npm run build --if-present
            - npm test
  ```  

  Чтобы протестировать CI\CD-процесс, отправьте в ветку `main` коммит со следующими файлами:
  * `index.js`:

    ```js
    //index.js

    function helloNpm() {
        return "hello SourceCraft CI/CD"
    }

    module.exports = helloNpm
    ```

  * `package.json`:

    ```json
    {
        "name": "sourcecraft-samples-nodejs",
        "version": "1.0.0",
        "description": "Sample for SourceCraft CI/CD",
        "license": "MIT",
        "author": "SourceCraft Team",
        "type": "commonjs",
        "main": "index.js",
        "scripts": {
          "test": "echo \"test passed\""
        }
    }
    ```

  * `package-lock.json`:

    ```json
    {
        "name": "sourcecraft-samples-nodejs",
        "version": "1.0.0",
        "lockfileVersion": 3,
        "requires": true,
        "packages": {
          "": {
            "name": "sourcecraft-samples-nodejs",
            "version": "1.0.0",
            "license": "MIT"
          }
        }
    }
    ```

- Java

  ```yaml
  # Этот рабочий процесс (workflow) соберет Java-проект с помощью Maven
  on:
    push:
      - workflows: publish-package-workflow
        filter:
          branches: ["main"]

  workflows:
    publish-package-workflow:
      settings:
        max_cube_duration: 10m
      tasks:
        - build-publish-task

  tasks:
    - name: build-publish-task
      cubes:
        - name: setup-jdk-maven
          script:
            - sudo apt install openjdk-21-jdk -y
            - sudo apt install maven -y
            - java --version
            - mvn --version
        - name: test
          script:
            - echo 'test'
        - name: package
          script:
            - mvn package
          # Опционально: выгрузка артефакта с именем
          # sourcecraft-sample-maven-1.0-SNAPSHOT.jar из целевой директории.
          # Артефакт можно скачать из кубика в разделе CI/CD
          #artifacts: 
          #  paths:
          #    - target/sourcecraft-sample-maven-1.0-SNAPSHOT.jar
  ```

  Добавьте в файл `.gitignore` данные, специфичные для тестирования приложений на Java.

  {% cut "Пример .gitignore" %}

  <!-- source: ru/_includes/sourcecraft/ci-cd/java-gitignore.md -->
  ```text
  ##############################
  ## Java
  ##############################
  .mtj.tmp/
  *.class
  *.jar
  *.war
  *.ear
  *.nar
  hs_err_pid*
  replay_pid*

  ##############################
  ## Maven
  ##############################
  target/
  pom.xml.tag
  pom.xml.releaseBackup
  pom.xml.versionsBackup
  pom.xml.next
  pom.xml.bak
  release.properties
  dependency-reduced-pom.xml
  buildNumber.properties
  .mvn/timing.properties
  .mvn/wrapper/maven-wrapper.jar

  ##############################
  ## Gradle
  ##############################
  bin/
  build/
  .gradle
  .gradletasknamecache
  gradle-app.setting
  !gradle-wrapper.jar

  ##############################
  ## IntelliJ
  ##############################
  out/
  .idea/
  .idea_modules/
  *.iml
  *.ipr
  *.iws

  ##############################
  ## Eclipse
  ##############################
  .settings/
  bin/
  tmp/
  .metadata
  .classpath
  .project
  *.tmp
  *.bak
  *.swp
  *~.nib
  local.properties
  .loadpath
  .factorypath

  ##############################
  ## NetBeans
  ##############################
  nbproject/private/
  build/
  nbbuild/
  dist/
  nbdist/
  nbactions.xml
  nb-configuration.xml

  ##############################
  ## Visual Studio Code
  ##############################
  .vscode/
  .code-workspace

  ##############################
  ## OS X
  ##############################
  .DS_Store

  ##############################
  ## Miscellaneous
  ##############################
  *.log
  ```
  <!-- endsource: ru/_includes/sourcecraft/ci-cd/java-gitignore.md -->

  {% endcut %}

  Чтобы протестировать CI\CD-процесс, отправьте в ветку `main` коммит со следующими файлами:

  * `pom.xml`:

    <!-- source: ru/_includes/sourcecraft/ci-cd/pom-xml-for-java.md -->
    ```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <groupId>com.mycompany.app</groupId>
      <artifactId>sourcecraft-sample-maven</artifactId>
      <version>1.0-SNAPSHOT</version>

      <name>bondarevsky-maven</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>17</maven.compiler.release>
      </properties>

      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.junit</groupId>
            <artifactId>junit-bom</artifactId>
            <version>5.11.0</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>

      <dependencies>
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-api</artifactId>
          <scope>test</scope>
        </dependency>
        <!-- Optionally: parameterized tests support -->
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-params</artifactId>
          <scope>test</scope>
        </dependency>
      </dependencies>

      <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
          <plugins>
            <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.4.0</version>
            </plugin>
            <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.3.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.13.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>3.3.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.4.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>3.1.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>3.1.2</version>
            </plugin>
            <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
            <plugin>
              <artifactId>maven-site-plugin</artifactId>
              <version>3.12.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-project-info-reports-plugin</artifactId>
              <version>3.6.1</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
    ```
    <!-- endsource: ru/_includes/sourcecraft/ci-cd/pom-xml-for-java.md -->

  * `src/test/java/com/mycompany/app/AppTest.java`:

    ```java
    package com.mycompany.app;

    import static org.junit.jupiter.api.Assertions.assertTrue;

    import org.junit.jupiter.api.Test;

    /**
     * Unit test for simple App.
     */
    public class AppTest {

        /**
         * Rigorous Test :-)
         */
        @Test
        public void shouldAnswerWithTrue() {
            assertTrue(true);
        }
    }
    ```

  * `src/main/java/com/mycompany/app/App.java`:

    ```java
    package com.mycompany.app;

    /**
     * Hello world!
     */
    public class App {
        public static void main(String[] args) {
            System.out.println("Hello World!");
        }
    }
    ```

{% endlist %}

#### Полезные ссылки {#see-also}

* [Шаблоны репозиториев](https://sourcecraft.dev/sourcecraft/repos)
* [Как начать работать с SourceCraft](https://sourcecraft.dev/portal/docs/ru/sourcecraft/quickstart.md)
* [Непрерывная интеграция и непрерывное развертывание в SourceCraft](https://sourcecraft.dev/portal/docs/ru/sourcecraft/concepts/ci-cd.md)
* [Справочник CI/CD](https://sourcecraft.dev/portal/docs/ru/sourcecraft/ci-cd-ref/index.md)
* [Настройка CI/CD с Yandex Cloud Functions](https://sourcecraft.dev/portal/docs/ru/sourcecraft/tutorials/ci-cd-sourcecraft-functions.md)
* [Запустить рабочий процесс вручную в репозитории SourceCraft](https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/run-workflow-manually.md)
* [Настроить вебхук в репозитории SourceCraft](https://sourcecraft.dev/portal/docs/ru/sourcecraft/operations/webhooks.md)
