Continuous integration and continuous deployment in SourceCraft
Continuous Integration/Continuous Deployment is a set of practices and tools you can use to automatically change, test, and deploy code. The approach allows you to continuously improve software quality and speed up development.
Continuous integration (CI)
CI is there for frequent and regular integration of code changes into the main branch of the repository. Each commit goes through automatic checks, e.g., unit tests and static code analysis. Thus you can make sure your commit is correct and the code is stable. This reduces the risks of integration issues, and the developers get the feedback faster.
Continuous deployment (CD)
The CD approach is built around automated code deployment on product servers after a code quality test. Be confident that your apps are always deployed and have the latest updates and fixes.
CI/CD configuration
SourceCraft offers some tools to manage CI/CD workflows.
The CI/CD configuration is set up for a particular repository and stored in a file named .sourcecraft/ci.yaml
.
General format of the .sourcecraft/ci.yaml
configuration file:
on:
pull_request:
- workflows: [<list_of_workflows>]
filter:
source_branches: [<list_of_source_branches>]
target_branches: [<list_of_target_branches>]
paths: [<list_of_paths>]
push:
- workflows: [<list_of_workflows>]
filter:
branches: [<list_of_branches>]
paths: [<list_of_paths>]
workflows:
<workflow_name>:
tasks:
- name: <task_name>
cubes:
- name: <cube_name>
image: <Docker_image_path>
script:
- <executed_script>
...
You can either use nested structure for configuration elements or mark them up as separate sections.
Example of CI/CD configuration marked up as separate sections
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
image: docker.io/library/node
script:
- echo Hello, world!
The configuration file supports secrets. For details, see Using the value of a secret in CI/CD.
See the templates repository in SourceCraft for the full specification of the .sourcecraft/ci.yaml
file.
Warning
Support for storing configurations for CI/CD, approval rules, and branch policies in a single .src.ci.yaml
file at the repository root will soon be discontinued. Use the separate .sourcecraft/ci.yaml
, .sourcecraft/review.yaml
, and .sourcecraft/branches.yaml
files.
For more information about working with CI/CD, see Configuring CI/CD in a SourceCraft repository.
Trigger events (on)
Under on
, you can configure the trigger events that will start the CI/CD workflows in the repository.
Such events may include pushing changes to a remote repository branch or creating a pull request.
You can configure different workflows for different events. You can also configure triggers for specific branches or paths in the repository.
For more information, see Trigger events (on) in the CI/CD reference.
Workflows
The workflows
section lists CI/CD workflows.
A workflow helps you organize tasks related to a certain CI/CD stage into a logical sequence.
For example, a single workflow may run for builds, tests, linting, code coverage verification, etc. All these steps will be different tasks as part of such a workflow. Then, you may have another workflow to generate documentation and deploy the new version to production.
All workflows are run concurrently.
For more information, see Workflows in the CI/CD reference.
Tasks
The tasks
section defines a list of tasks that are part of the workflow.
Each task contains a series of minimum logical actions, i.e., cubes. The result of a task is when all its cubes are completed.
Note
All cubes within a single task are run on the same VM (worker). This way, if a cube changes the worker environment, such as installs a package, creates or deletes a file, etc., such environment will still be there for all other cubes running within a single task. For example, one cube may install the runtime
package for Go, another one runs the go build
command, and the next one runs go test
. To learn more about environment variable inheritance, see Cubes.
If the cubes are run in different tasks, they are guaranteed to run on different workers.
By default, a task starts with cloning the repository.
All workflow tasks are started concurrently.
In tasks and cubes, you can use environment variables and secrets.
For more information on tasks, see Tasks in the CI/CD reference.
Cubes
The cubes
section lists the minimum logical actions, i.e., cubes, to execute within a task.
Such a minimum action may be calling a script, starting a Docker container, or calling a script in a Docker container.
The following cube types are available:
-
Native: Runs directly on a worker.
If a native cube, while running, changes the worker environment, such as installs a package, creates or deletes a file, etc., such environment will still be there for all other cubes running within a single task.
-
Docker cube: Runs within a Docker container started on a worker. Technically, it runs a custom script or a container script, if the container has an entry point.
If a Docker cube, while running, changes the environment, such environment will be available to other cubes within the task only in case the changes were made within the
/sourcecraft
directory. All other changes will be removed along with the Docker container.When working from a container, the directories are mounted as follows:
- The directory housing files associated with the task in progress is mounted to
/sourcecraft
. - The directory to clone the repository to and that is also the working directory (
workdir
) by default, is mounted to/sourcecraft/workspace
.
You can get the paths of these directories from the
$SOURCECRAFT_ROOT_DIRECTORY
and$SOURCECRAFT_WORKSPACE
predefined environment variables, respectively.To configure a Docker cube, use the image property to specify the Docker image name and, optionally, username, password, entry point, and arguments.
- The directory housing files associated with the task in progress is mounted to
In cubes, you can use environment variables and secrets. To provide environment variables from a certain cube to others as KEY=VALUE
pairs, you can use the $SOURCECRAFT_ENV
predefined variable.
By default, cubes within a single task are run one by one. To link cubes, use the needs
property, where you can specify the list of cubes to execute before the current one. If you skip this property, the cube will depend on the one defined immediately before it.
The artifacts that may be created after the cube is run are saved for further use. They will be available for download from the cube in the
For more information on cubes, see Cubes in the CI/CD reference.
Environment variables in CI/CD
The SourceCraft CI/CD processes support environment variables. You can set the variables under the following items in the .sourcecraft/ci.yaml
configuration file:
- Task: To provide the variables to all cubes linked to the task.
- Cube: To provide the variables to the specified cube.
Also, you can use predefined environment variables.
Warning
Do not store any sensitive data, such as passwords, access keys, or tokens, in environment variables; use secrets instead.
Example of a configuration with environment variables
tasks:
- name: my-task
# Defines the variables to go to all the cubes associated with the task.
env:
TASK_VAR: test-var-'test'-\"test\"
MULTILINE_VAR: |
multi-var
multi-var
this is my multi-var
cubes:
- name: my-cube
# Defines the variables to go only to a specific cube.
env:
CUBE_VAR: "you can see me here only"
SECRET_VAR: ${{ secrets.<secret_name> }}
script:
- echo "$TASK_VAR"
- echo "$MULTILINE_VAR"
- echo "$CUBE_VAR"
- echo "$SECRET_VAR"
For more information about using environment variables, see Processing environment variables in SourceCraft.
Workers
Workers are virtual machines, physical servers, or serverless containers used to run CI/CD processes.
All cubes within a single task run on the same worker.
The following worker types are supported:
Cloud workers
Cloud workers are cloud-based virtual machines provided by SourceCraft. They are the default resource for the CI/CD processes.
Cloud worker computing resource configuration: 4 vCPUs, 8 GB RAM.
Serverless workers
Serverless workers are cloud-based serverless containers provided by SourceCraft. Unlike cloud workers, serverless workers start almost instantly as there is no need to boot up a VM.
Limitations:
- Only Yandex Container Registry is supported for Docker cubes.
- You cannot run
docker
ordocker-compose
within a cube. - A single job can include no more than nine unique custom Docker images.
To run a CI/CD process on a serverless worker, specify runs_on: serverless
in the workflow (workflow
) or task (task
) parameters.
If runs_on
is not specified in task
, it will default to the parameter from workflow:runs_on
.
Example of running the whole workflow on a serverless worker
workflows:
workflow-in-serverless-mode:
runs_on: serverless
tasks:
- name: task1-in-serverless-mode
cubes:
- name: hello
script:
- echo "hello from serverless"
- name: task2-in-serverless-mode
cubes:
- name: hello
script:
- echo "hello from serverless again"
Example of running an individual task on a serverless worker
workflows:
workflow1:
tasks:
- name: task1-in-compute-mode
cubes:
- name: hello
script:
- echo "hello from compute"
- name: task2-in-serverless-mode
runs_on: serverless
cubes:
- name: hello
script:
- echo "hello from serverless"
Self-hosted workers
Self-hosted workers are users’ personal servers, both virtual and physical, on which CI/CD processes run. These processes will have access to the user server environment.
Restrictions on the amount of computing resources do not apply to self-hosted workers, and they also do not consume the total CI/CD runtime quota.
For more information, see Setting up a self-hosted worker for SourceCraft.
To run a CI/CD process on a custom self-hosted worker, specify runs_on: self-hosted
in the workflow (workflow
) or task (task
) parameters.
If runs_on
is not specified in task
, the parameter from workflow:runs_on
will be used by default.
Example of running the whole workflow on a self-hosted worker
workflows:
my-awesome-workflow:
runs_on: self-hosted
tasks:
- name: self-hosted-task
cubes:
- name: hello
script:
- echo "hello from self-hosted"
- name: self-hosted-go-builder-task
runs_on: [self-hosted, go-builder]
cubes:
- name: hello
script:
- echo "hello from self-hosted go builder"
In this case, tasks from my-awesome-workflow
will run on any of your self-hosted workers by default unless their runs_on
parameter is redefined. At the same time, self-hosted-go-builder-task
will run only on the self-hosted worker assigned the go-builder
tag during initialization.