CI/CD: Continuous Integration and Deployment for Industrial Software
What Is CI/CD and Why It Matters for Industrial Software
CI/CD stands for Continuous Integration and Continuous Deployment. It automates building, testing, and deploying software every time a developer pushes code changes.
In industrial software, manual deployments are risky. A human can forget a step, deploy the wrong version, or skip tests under pressure. CI/CD creates an automated pipeline that runs the same steps every time, consistently and reliably. Every push triggers compilation and testing, only passing code gets deployed, and the audit trail shows exactly what changed, when, and by whom.
GitHub Actions: Your First Pipeline
GitHub Actions is a CI/CD platform built into GitHub. Pipelines are defined in YAML files inside .github/workflows/.
# .github/workflows/ci.yml
name: Factory Monitor CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --release
Every workflow needs a trigger (on), one or more jobs, and steps within each job.
Build Stage: Compiling and Creating the Image
The build stage compiles your Rust application and creates a Docker image:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- run: cargo build --release
- run: |
docker build -t factory-monitor:${{ github.sha }} .
docker tag factory-monitor:${{ github.sha }} factory-monitor:latest
- run: |
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker tag factory-monitor:latest ghcr.io/${{ github.repository }}/factory-monitor:latest
docker push ghcr.io/${{ github.repository }}/factory-monitor:latest
The caching step significantly speeds up builds by reusing previously downloaded dependencies.
Test Stage: Automated Testing
A bug in a factory monitoring system can mean missed alerts and equipment damage. Test before deploying:
test:
runs-on: ubuntu-latest
needs: build
services:
surrealdb:
image: surrealdb/surrealdb:v2.1.4
ports:
- 8000:8000
options: >-
--health-cmd "curl -f http://localhost:8000/health"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --lib
- run: cargo test --test '*'
env:
DATABASE_URL: ws://localhost:8000
- run: cargo clippy -- -D warnings
- run: cargo fmt --check
The services block spins up a real SurrealDB instance for integration tests.
Deploy Stage: Automatic Deployment to VPS
After tests pass, deploy the new version via SSH:
deploy:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
cd /opt/factory-monitor
docker compose pull
docker compose up -d --remove-orphans
sleep 10
curl -f http://localhost:8080/health || exit 1
Store secrets in GitHub under Settings > Secrets and Variables > Actions: VPS_HOST, VPS_USER, VPS_SSH_KEY, and REGISTRY_TOKEN.
Practical Example: Complete Pipeline for a Rust Application
Here is the full workflow combining all stages:
name: Factory Monitor Pipeline
on:
push:
branches: [main]
env:
CARGO_TERM_COLOR: always
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo fmt --check
- run: cargo clippy -- -D warnings
test:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- run: cargo test --all
deploy:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- name: Build and push
run: |
docker build -t factory-monitor:latest .
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push ghcr.io/${{ github.repository }}/factory-monitor:latest
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
cd /opt/factory-monitor
docker compose pull && docker compose up -d
Summary
CI/CD automates the path from code change to production deployment. GitHub Actions provides a free, integrated platform for Rust projects. The pipeline consists of three stages: build (compile and create images), test (run automated checks), and deploy (push to the production server). In the next lesson, you will learn monitoring with Prometheus and Grafana to observe your deployed applications in real time.