Artifacts: dsci@a1abc69. File: answer.md


artifacts

**File structure** ``` .dsci/ ├── jobs.yaml ├── test_job/ │ ├── job.bash │ └── tasks/ │ ├── run_tests/ │ │ └── task.bash │ └── check_coverage/ │ └── task.py ├── build_job/ │ ├── job.bash │ └── tasks/ │ └── build_image/ │ └── task.bash └── push_job/ ├── job.bash └── tasks/ └── push_image/ └── task.py ``` --- ## `.dsci/jobs.yaml` ```yaml # DSCI pipeline – Ruby project jobs: # ------------------------------------------------- # 1️⃣ Test job – runs unit‑tests and checks coverage # ------------------------------------------------- - id: test path: test_job/ params: minimal: 80 # minimal coverage % (pipeline input) version: "0.0.0" # dummy – not used here # ------------------------------------------------- # 2️⃣ Build job – builds Docker image # ------------------------------------------------- - id: build path: build_job/ params: version: "0.0.0" # will be overridden by pipeline input # ------------------------------------------------- # 3️⃣ Push job – pushes image to the registry # ------------------------------------------------- - id: push path: push_job/ params: version: "0.0.0" # same tag as the build job ``` > **How to inject real values** – when you trigger the pipeline you can override the > `minimal` and `version` parameters (e.g. via the UI, API or CI‑system variables). > Inside the jobs/tasks they are accessed with `config()` (Python) or `$(config …)` (Bash). --- ## `test_job/job.bash` ```bash #!/bin/bash # ------------------------------------------------- # Test job – orchestrates the two tasks # ------------------------------------------------- set -e # 1️⃣ Run the test suite (produces a coverage report) run_task "run_tests" # 2️⃣ Verify that coverage ≥ minimal required value run_task "check_coverage" ``` ### `test_job/tasks/run_tests/task.bash` ```bash #!/bin/bash set -e # Install Ruby dependencies bundle install --jobs=4 --quiet # Run the test suite – replace with your actual test command # For demonstration we just simulate a successful run bundle exec rake test # ----------------------------------------------------------------- # SimpleCov (or any coverage tool) would normally write a report. # Here we simulate a coverage number and store it as an artifact. # ----------------------------------------------------------------- # Example: 85.0 % coverage echo "85.0" > ~/artifacts/coverage.txt ``` ### `test_job/tasks/check_coverage/task.py` ```python #!/usr/bin/python3 import sys, os # ----------------------------------------------------------------- # Read pipeline parameters # ----------------------------------------------------------------- cfg = config() minimal = float(cfg.get("minimal", 0)) # ----------------------------------------------------------------- # Read the coverage value produced by the previous task # ----------------------------------------------------------------- coverage_file = os.path.expanduser("~/artifacts/coverage.txt") try: with open(coverage_file, "r", encoding="utf-8") as f: coverage = float(f.read().strip()) except Exception as e: print(f"❌ Unable to read coverage: {e}", file=sys.stderr) sys.exit(1) print(f"🔎 Coverage reported: {coverage}% (minimum required: {minimal}%)") if coverage < minimal: print("❌ Coverage is below the required threshold – failing pipeline.", file=sys.stderr) sys.exit(1) print("✅ Coverage meets the minimal requirement.") ``` --- ## `build_job/job.bash` ```bash #!/bin/bash # ------------------------------------------------- # Build job – creates a Docker image and exports its name # ------------------------------------------------- set -e run_task "build_image" ``` ### `build_job/tasks/build_image/task.bash` ```bash #!/bin/bash set -e # ----------------------------------------------------------------- # Get the image tag (pipeline parameter) # ----------------------------------------------------------------- VERSION=$(config version) # ----------------------------------------------------------------- # Define the full image name (adjust registry / repository as needed) # ----------------------------------------------------------------- IMAGE_NAME="myregistry.example.com/my-ruby-app:${VERSION}" echo "🛠️ Building Docker image ${IMAGE_NAME}" docker build -t "${IMAGE_NAME}" . # ----------------------------------------------------------------- # Export the image name for downstream jobs # ----------------------------------------------------------------- # The SDK will automatically prefix the key with the job id under _dsci_ update_state "image" "${IMAGE_NAME}" ``` --- ## `push_job/job.bash` ```bash #!/bin/bash # ------------------------------------------------- # Push job – pushes the image built by the previous job # ------------------------------------------------- set -e run_task "push_image" ``` ### `push_job/tasks/push_image/task.py` ```python #!/usr/bin/python3 import os, sys, subprocess # ----------------------------------------------------------------- # Load pipeline parameters (version is kept as a fallback) # ----------------------------------------------------------------- cfg = config() fallback_version = cfg.get("version", "latest") # ----------------------------------------------------------------- # Retrieve state from the *build* job # ----------------------------------------------------------------- state = get_state() build_state = state.get("_dsci_", {}).get("build", {}) image = build_state.get("image