Diferență între revizuiri ale paginii „SDPT Lab 6”

De la WikiLabs
Jump to navigationJump to search
 
Linia 23: Linia 23:
 
git init
 
git init
 
git branch -m main
 
git branch -m main
git remote add origin https://gitlab.com/<your-username>/sdpt-smart-oven.git
+
git remote add origin https://gitlab.cs.pub.ro/<your-username>/sdpt-smart-oven.git
 
git add .
 
git add .
 
git commit -m "Initial commit: Oven Controller with CMake and Docker"
 
git commit -m "Initial commit: Oven Controller with CMake and Docker"
Linia 48: Linia 48:
 
docker exec -it my-local-runner gitlab-runner register
 
docker exec -it my-local-runner gitlab-runner register
 
</syntaxhighlight>
 
</syntaxhighlight>
* '''GitLab instance URL:''' <code>https://gitlab.com/</code>
+
* '''GitLab instance URL:''' <code>https://gitlab.cs.pub.ro/</code>
 
* '''Registration token:''' (Paste your token from step 1)
 
* '''Registration token:''' (Paste your token from step 1)
 
* '''Description:''' My Laptop Runner
 
* '''Description:''' My Laptop Runner

Versiunea curentă din 20 aprilie 2026 17:49

Week 6 Lab Activity: CI/CD Pipelines & Custom Runners

Objective

Today, we automate everything. You will transition from compiling code on your laptop to architecting a professional CI/CD pipeline.

We will accomplish this in six phases:

  1. Repository Setup: Migrating your code to GitLab.
  2. Infrastructure: Spinning up and registering your own local GitLab Runner via Docker.
  3. Continuous Integration (Build): Writing your first CI job and generating Artifacts.
  4. Continuous Integration (Test): Consuming Artifacts and testing via QEMU.
  5. Continuous Deployment (CD): Creating a simulated OTA firmware release restricted to the main branch.
  6. Cleanup: Deregistering and destroying your local runner.

Phase 1: Repository Setup

1. Create a Project: Log into GitLab and create a new blank project named sdpt-smart-oven. Uncheck "Initialize repository with a README".

2. Push Your Code: Open your terminal on your laptop, navigate to your Week 5 project folder, and push your code to this new repository.

git init
git branch -m main
git remote add origin https://gitlab.cs.pub.ro/<your-username>/sdpt-smart-oven.git
git add .
git commit -m "Initial commit: Oven Controller with CMake and Docker"
git push -u origin main

Phase 2: Registering a Local Runner

GitLab provides shared runners, but embedded systems often require custom hardware or specific toolchains. We will host our own Runner!

1. Get Your Registration Token: In your GitLab project, go to Settings -> CI/CD. Expand the Runners section. Under "Project runners", click "New project runner". Add the tag local-embedded and click Create. Copy the registration token it gives you.

2. Start the Runner via Docker: On your laptop terminal, run a background Docker container to act as your runner. (We mount the Docker socket so the runner can spawn its own containers!)

docker run -d --name my-local-runner --restart always -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest

3. Register the Runner: Now, execute the registration command inside the running container:

docker exec -it my-local-runner gitlab-runner register
  • GitLab instance URL: https://gitlab.cs.pub.ro/
  • Registration token: (Paste your token from step 1)
  • Description: My Laptop Runner
  • Tags: local-embedded
  • Executor: docker
  • Default image: ubuntu:22.04

Refresh your GitLab Runners page. You should see a green circle indicating your local runner is alive and listening for jobs!


Phase 3: The Build Stage & Artifacts

We will now tell your Runner how to build our code. Create a file named exactly .gitlab-ci.yml in your project root.

Your Challenge (Part 1):

  1. Image: Set image: to the ARM Docker image you built last week.
  2. Stages: Define three stages: build, test, and deploy.
  3. The Build Job: Create a job named compile_firmware.
    • Assign it to the build stage.
    • Use tags: [local-embedded] to force this job to run on YOUR laptop's runner.
    • In the script, run CMake for aarch64 and run make.
    • Create artifacts to save the build/ directory (expire in 1 hour).

Commit and push. Watch the pipeline in GitLab. Your laptop's fan might spin up because *your* Docker daemon is doing the heavy lifting!


Phase 4: The Test Stage & Merge Checks

Your Challenge (Part 2): Add a job named verify_logic:

  1. Stage: test
  2. Tags: local-embedded
  3. dependencies: Require the artifacts from compile_firmware.
  4. script: Navigate to build/ and execute tests using QEMU (qemu-aarch64 -L /usr/aarch64-linux-gnu/ ./unit_tests).

Test the Block:

  1. Go to GitLab Settings -> Merge Requests -> Check "Pipelines must succeed".
  2. Create a new branch: git checkout -b feature/broken-math
  3. Break an assertion in your C++ tests and push the branch.
  4. Open a Merge Request. Watch the test stage fail and observe the Merge button physically lock you out! Fix the code, push again, and Merge it.

Phase 5: Continuous Deployment (CD)

Once the code hits the main branch, we want to handle two different types of deployments: an automated OTA release (Pull), and an on-demand Edge deployment (Push).

Your Challenge (Part 3): Automated OTA Release Add a job named release_ota_firmware:

  1. Stage: deploy
  2. Tags: local-embedded
  3. dependencies: Pull from compile_firmware.
  4. script: Rename your binary to a release format and simulate cryptographically signing it:
    • mv build/unit_tests build/firmware_v1.bin
    • echo "CRYPTOGRAPHIC_SIGNATURE_OK" >> build/firmware_v1.bin
  5. Rules: We ONLY want to release firmware automatically from the main branch! Add a rules: section with - if: '$CI_COMMIT_BRANCH == "main"'.
  6. Artifacts: Save build/firmware_v1.bin as an artifact that never expires.

Your Challenge (Part 4): On-Demand Push Deployment Sometimes we need to instantly push an update to a specific machine (e.g., a prototype in the lab) without waiting for it to poll. We will simulate an SSH deployment using pipeline variables.

Add another job named deploy_to_edge_device:

  1. Stage: deploy
  2. Tags: local-embedded
  3. dependencies: Pull from compile_firmware.
  4. Rules: We want this to be an "On-Demand" job that requires a human to click a play button. Add a rules: section with - when: manual.
  5. script: Simulate securely pushing the binary to a specific IP address using an environment variable ($TARGET_IP). Do not hardcode an IP here; we will inject it later!
    • echo "Connecting to Edge Device at $TARGET_IP..."
    • echo "scp build/unit_tests admin@$TARGET_IP:/opt/smart-oven/bin/"
    • echo "Deployment to $TARGET_IP successful!"

Test the Deployments:

  1. Push your code to main.
  2. You will see the release_ota_firmware job run automatically.
  3. The deploy_to_edge_device job will be paused (marked with a "Play" icon).
  4. Click the Play icon. GitLab will take you to a new screen asking if you want to inject any environment variables.
  5. Add a variable with the Key TARGET_IP and the Value 192.168.1.50 (or any dummy IP address you prefer).
  6. Click "Run job" and check the terminal output to see your variable successfully injected into the simulated SSH command!

Phase 6: Cleanup

To prevent your runner from polling GitLab forever and draining your laptop battery, gracefully shut it down and remove it:

docker stop my-local-runner
docker rm my-local-runner

In the GitLab UI, go back to Settings -> CI/CD -> Runners, and delete the offline runner.


Assignment Submission

Upload ONLY your finalized .gitlab-ci.yml to the Moodle VPL assignment. The automated grading server will analyze your YAML syntax to ensure you correctly configured the stages, artifacts, custom runner routing, and deployment rules.