Настроить CI/CD в репозитории SourceCraft
В SourceCraft встроен механизм для работы с CI/CD-процессами.
Конфигурация CI/CD задается для конкретного репозитория и хранится в корне репозитория в файле .src.ci.yaml
.
Общий вид конфигурационного файла .src.ci.yaml
:
on:
pull_request:
- workflows: [<список_рабочих_процессов>]
filter:
source_branches: [<список_исходных_веток>]
target_branches: [<список_целевых_веток>]
paths: [<список_путей>]
push:
- workflows: [<список_рабочих_процессов>]
filter:
branches: [<список_веток>]
paths: [<список_путей>]
workflows:
<имя_рабочего_процесса>:
tasks:
- name: <имя_задачи>
cubes:
- name: <имя_кубика>
image: <путь_к_Docker-образу>
script:
- <выполняемый_скрипт>
...
В конфигурационном файле поддерживается использование секретов. Подробнее см. в разделе Использовать значение секрета в CI/CD.
Полную спецификацию файла .src.ci.yaml
см. в репозитории templates в SourceCraft.
CI/CD-процессы запускаются событиями-триггерами. Такими событиями могут быть отправка изменений в ветку удаленного репозитория или создание пул-реквеста.
Для разных событий вы можете настроить разные рабочие процессы. Также срабатывание триггеров можно настроить для конкретных веток или путей в репозитории.
Описание элементов конфигурации см. справочнике CI/CD.
Вы можете настроить CI/CD при создании репозитория или в уже имеющемся.
Настроить CI/CD при создании репозитория
-
Откройте главную страницу SourceCraft.
-
На панели слева нажмите
-
В открывшемся окне задайте параметры репозитория.
-
В блоке Configuration выберите Add a src yaml template.
-
В выпадающем списке YAML выберите шаблон конфигурации CI/CD:
Docker
;HelloWorld
;Java
;NodeJS
;Python
.
Содержимое шаблонов см. в подразделе Примеры.
-
Нажмите Create repository.
В корне созданного репозитория будет размещен файл
.src.yaml
с шаблоном конфигурации CI/CD.
Настроить CI/CD в уже имеющемся репозитории
-
Откройте главную страницу SourceCraft.
-
На вкладке
-
Выберите репозиторий, в котором хотите настроить CI/CD.
-
Склонируйте репозиторий:
-
В правом верхнем углу нажмите кнопку
-
В зависимости от способа подключения скопируйте ссылку для клонирования репозитория.
-
В терминале выполните команду:
git clone <ссылка_для_клонирования_репозитория>
-
Перейдите в склонированный репозиторий:
cd <имя_репозитория>
-
-
Сформируйте файл конфигурации CI/CD
.src.ci.yaml
согласно описанию в справочнике CI/CD или воспользуйтесь шаблонами из подраздела Примеры. -
Добавьте файл конфигурации CI/CD в индекс
git
, сделайте коммит и отправьте изменения в веткуmain
:git add .src.ci.yaml git commit -m "Added CI/CD configuration" git push -u origin main
Проверить выполнение CI/CD-процесса
-
В зависимости от настроек, указанных в
.src.ci.yaml
, выполните событие-триггер. -
Проверьте выполнение CI/CD-процесса:
- На странице репозитория в разделе
- Выберите запущенный рабочий процесс (workflow).
- На открывшейся странице будут отображены все задачи (tasks) рабочего процесса, шаги задач — кубики (cubes), а также статусы и результаты выполнения.
- На странице репозитория в разделе
Примеры
# Это базовый рабочий процесс (workflow), который
# поможет вам начать работу с SourceCraft CI/CD
# Настройка события-триггера для запуска рабочего процесса
on:
# Запуск рабочего процесса по отправке изменений в ветку main
# удаленного репозитория или создание пул-реквеста в ветку main
pull_request:
- workflows: [sample-workflow]
filter:
source_branches: ["**", "!test**"]
target_branches: "master"
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.
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
:
FROM alpine
CMD ["echo", "Hello World!!"]
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.
Пример .gitignore
# 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
Чтобы протестировать CI\CD-процесс, отправьте в ветку main
коммит с файлом main.py
:
print('Hello SourceCraft')
print('Hello SourceCraft')
for i in range(10):
print(i)
# input
hi = input()
print(hi)
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
://index.js function helloNpm() { return "hello SourceCraft CI/CD" } module.exports = helloNpm
-
package.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
:{ "name": "sourcecraft-samples-nodejs", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sourcecraft-samples-nodejs", "version": "1.0.0", "license": "MIT" } } }
# Этот рабочий процесс (workflow) соберет Java-проект с помощью Maven
on:
push:
- workflows: publish-package-workflow
filter:
branches: ["main"]
workflows:
publish-package-workflow:
settings:
max-cube-duration: 10m
retry: 2
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.
Пример .gitignore
##############################
## 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
Чтобы протестировать CI\CD-процесс, отправьте в ветку main
коммит со следующими файлами:
-
pom.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>
-
src/test/java/com/mycompany/app/AppTest.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
:package com.mycompany.app; /** * Hello world! */ public class App { public static void main(String[] args) { System.out.println("Hello World!"); } }