Artifacts: dsci@1c9fb55.1789573431. File: answer.md
## 1️⃣ Repository layout for the **Rakulang** DSCI pipeline
```
.
├── jobs.yaml # pipeline definition (list of jobs)
└── .dsci
├── install_deps/
│ ├── job.bash # job that installs system deps
│ └── tasks/
│ └── sys_packages/
│ └── task.bash # installs sqlite3 & curl
├── mariadb/
│ ├── config.yaml # default DB credentials (can be overridden)
│ ├── job.bash # job that installs & starts MariaDB
│ └── tasks/
│ └── start/
│ └── task.bash # installs mariadb, creates DB & exports state
└── test/
├── job.bash # job that runs unit‑tests with prove6
└── tasks/
└── run_prove/
└── task.bash # executes `prove6 -r t/`
```
---
## 2️⃣ `jobs.yaml` – only the **job list** (no logic, no matrices)
```yaml
# .dsci/jobs.yaml
jobs:
- id: install_deps
path: .dsci/install_deps/
- id: mariadb
path: .dsci/mariadb/
# you could override defaults here, e.g.
# params:
# db_user: ci_user
# db_pass: super_secret
# db_name: rakulang
- id: test
path: .dsci/test/
```
*Each entry only declares the job id and where its source lives.
All the real work lives in the `job.*` / `task.*` files.*
---
## 3️⃣ Job **install_deps** – Bash job that calls a single task
### `install_deps/job.bash`
```bash
#!/usr/bin/env bash
# .dsci/install_deps/job.bash
# Run the only task in this job
run_task "sys_packages"
```
### `install_deps/tasks/sys_packages/task.bash`
```bash
#!/usr/bin/env bash
# .dsci/install_deps/tasks/sys_packages/task.bash
set -euo pipefail
echo "=== Installing system dependencies (sqlite3 & curl) ==="
# DSCI jobs usually run in an Alpine container – use apk.
# If you run on Debian/Ubuntu replace with apt‑get.
if command -v apk >/dev/null 2>&1; then
apk update
apk add --no-cache sqlite curl
else
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y sqlite3 curl
fi
echo "=== System deps installed ==="
```
*No state is needed for this job – it just prepares the environment.*
---
## 4️⃣ Job **mariadb** – installs MariaDB, starts it as a background service and shares connection info via **state**
### `mariadb/config.yaml` *(default parameters, can be overridden in `jobs.yaml`)*
```yaml
# .dsci/mariadb/config.yaml
db_user: rakulang_user
db_pass: rakulang_pass
db_name: rakulang
db_port: 3306 # default MariaDB port inside the container
```
### `mariadb/job.bash`
```bash
#!/usr/bin/env bash
# .dsci/mariadb/job.bash
# Run the start task – it will install MariaDB, create DB/user,
# start the server and export the connection data as state.
run_task "start"
```
### `mariadb/tasks/start/task.bash`
```bash
#!/usr/bin/env bash
# .dsci/mariadb/tasks/start/task.bash
set -euo pipefail
# ------------------------------------------------------------------
# 1️⃣ Read job parameters (defaults are in config.yaml)
# ------------------------------------------------------------------
DB_USER=$(config db_user)
DB_PASS=$(config db_pass)
DB_NAME=$(config db_name)
DB_PORT=$(config db_port)
echo "=== Installing MariaDB ==="
if command -v apk >/dev/null 2>&1; then
apk update
apk add --no-cache mariadb mariadb-client
else
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-client
fi
echo "=== Initialising MariaDB data directory ==="
# Initialise the data directory if it is empty
if [ ! -d /var/lib/mysql/mysql ]; then
mariadb-install-db --user=mysql --datadir=/var/lib/mysql
fi
echo "=== Starting MariaDB in the background ==="
# Run MariaDB as a daemon (no systemd) – we keep the PID to stop later if needed
mysqld --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock &
MYSQL_PID=$!
# Give the server a few seconds to become ready
sleep 5
echo "=== Securing & creating DB/user ==="
# Basic security (no root password) and our test user
mysql -uroot <