I'm excited to share this guide on using GitLab CI/CD. In this article, we'll explore how to set up a CI/CD pipeline using YAML configuration files, include YAML files from directories within the project, automate notifications to Discord, and streamline tasks for a Rust project. My aim is to write about solutions to challenges I encounter, hoping to assist those who might face similar issues.
What is GitLab CI/CD?
GitLab CI/CD (Continuous Integration and Continuous Delivery) is a part of GitLab that allows you to automate the testing, building, and deployment of your code. With CI/CD pipelines, you can ensure that your code is always in a deployable state, catch bugs early, and automate repetitive tasks.
Prerequisite: Installing Rust
Before diving into GitLab CI/CD, you need to have Rust installed on your machine. You can install Rust by following the instructions on the official Rust website.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation, ensure that Rust is correctly installed by running:
rustup --version
cargo --version
Initializing a Rust Project
Let's start by creating a simple Rust project that calculates the factorial of a number.
1. Open your terminal and run the following command to create a new Rust project:
cargo new rust_project
2. Navigate to the project directory:
cd rust_project
3. Replace the contents of src/main.rs with the following code:
main.rs
fn factorial(n: u32) -> u32 {
match n {
0 => 1,
_ => n * factorial(n - 1),
}
}
fn main() {
let num = 5;
println!("The factorial of {} is {}", num, factorial(num));
}
4. Build and run the project to ensure everything is set up correctly:
cargo build
cargo run
Setting Up Your .gitlab-ci.yml
In this section, we will set up the primary .gitlab-ci.yml file located at the root of your project. This file defines the stages of your CI/CD pipeline and includes another YAML file for specific jobs. Including YAML files from directories within the project can help you organize and manage complex CI/CD configurations more effectively.
Why is Including YAML Files Important?
Including YAML files from different directories within your project helps in managing large and complex pipelines by breaking them into smaller, more manageable parts. This practice promotes reusability and maintainability of your CI/CD configurations.
This is how the project structure looks like:
rust_project/
├── Cargo.toml
├── src/
│ ├ ├── main.rs
│ ├──rust_project_ci.yml
├── .gitlab-ci.yml
└── README.md
.gitlab-ci.yml
stages:
- build
- test
- notification
include:
- local: 'rust_project/rust_project_ci.yml'
test_job:
image: alpine:latest
stage: test
script:
- echo 🕵🏻 Checking...
dependencies:
- build-job
success_notification:
image: alpine:latest
stage: notification
script:
- apk add --update git curl
- wget https://raw.githubusercontent.com/DiscordHooks/gitlab-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- /bin/ash ./send.sh success $DISCORD_WEBHOOK_SECRET
when: on_success
dependencies:
- build-job
failure_notification:
image: alpine:latest
stage: notification
script:
- apk add --update git curl
- wget https://raw.githubusercontent.com/DiscordHooks/gitlab-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- /bin/ash ./send.sh failure $DISCORD_WEBHOOK_SECRET
when: on_failure
dependencies:
- build-job
variables:
DISCORD_WEBHOOK_SECRET: "$DISCORD_WEBHOOK_SECRET"
Including a Rust Project CI Configuration
The rust_project/rust_project_ci.yml file handles the build and test jobs specific to the Rust project. Here's how it's set up:
rust_project_ci.yml
build-job:
stage: build
image: rust:latest
script:
- pwd
- ls
- ls rust_project
- cd rust_project
- cargo build --release
- cargo run
- apt-get update && apt-get install -y curl
- curl -I https://discord.com
rules:
- if: '$TRIGGER_CONTEXT == "pipeline_test"'
- if: '$TRIGGER_CONTEXT == "push"'
test-job:
stage: test
image: rust:latest
script:
- pwd
- ls
- ls rust_project
- cd rust_project
- cargo build --release
- cargo test
dependencies:
- build-job
rules:
- if: '$TRIGGER_CONTEXT == "pipeline_test"'
- if: '$TRIGGER_CONTEXT == "push"'
variables:
RUST_LOG: "info"
Explanation of Stages and Jobs
Build Stage: The build-job in rust_project_ci.yml handles the compilation and running of the Rust project. It includes steps to navigate into the project directory, build the project, and execute it. The build job also installs curl and checks connectivity to Discord as a sample task.
Test Stage: The test_job in .gitlab-ci.yml and test-job in rust_project_ci.yml are responsible for running tests. It ensures that all the tests in the Rust project pass without issues. Dependencies ensure that the build stage completes successfully before testing begins.
Notification Stage: This stage includes two jobs, success_notification and failure_notification, which notify you on Discord about the success or failure of the pipeline. These jobs use a shell script to send messages to a Discord webhook.
Automating Notifications with Discord Webhook
To automate notifications to Discord, follow these steps:
Create a Discord Webhook:
- Go to your Discord server settings.
- Navigate to the "Integrations" tab.
- Click "Create Webhook" and copy the webhook URL.
Set the Webhook URL as a GitLab Variable:
- Go to your GitLab project.
- Navigate to "Settings" > "CI / CD" > "Variables".
- Add a new variable with the key DISCORD_WEBHOOK_SECRET and paste the webhook URL as the value.
Conclusion
By following this guide, you should now have a basic understanding of setting up GitLab CI/CD for a Rust project. The pipeline automates the build, test, and notification processes, helping you maintain code quality and stay informed about the state of your project. Including YAML files from different directories promotes better organization and maintainability of your CI/CD configurations.
Feel free to reach out with any questions or feedback. Happy coding😊!
Top comments (0)