Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/scripts/smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,55 @@ trap cleanup EXIT
cd -- "${TMP_DIR}"
"${ROLL_BIN[@]}" env-init smoketest magento2
"${ROLL_BIN[@]}" config validate

# The version overview reads the catalog and the project config only, so it needs no network
echo "+ config versions"
"${ROLL_BIN[@]}" config versions >/dev/null

# Setting a version non-interactively must rewrite the pin in place. The registry lookup that
# would warn about an unknown tag is best-effort, so this passes with or without network access.
echo "+ config version php 8.2"
"${ROLL_BIN[@]}" config version php 8.2 >/dev/null 2>&1
if ! grep -q '^PHP_VERSION=8.2$' .env.roll; then
>&2 echo "FAIL: roll config version did not write PHP_VERSION=8.2"
exit 1
fi
if [[ "$(grep -c '^PHP_VERSION=' .env.roll)" != "1" ]]; then
>&2 echo "FAIL: roll config version left more than one PHP_VERSION line"
exit 1
fi

# Same again, so the "nothing to change" path is exercised and stays a success
"${ROLL_BIN[@]}" config version php 8.2 >/dev/null 2>&1

# A commented pin is replaced rather than duplicated (magento2's init.env ships one)
echo "+ config version opensearch 2.19"
"${ROLL_BIN[@]}" config version opensearch 2.19 >/dev/null 2>&1
if [[ "$(grep -c '^#*[[:space:]]*OPENSEARCH_VERSION=' .env.roll)" != "1" ]]; then
>&2 echo "FAIL: roll config version duplicated the commented OPENSEARCH_VERSION line"
exit 1
fi

# With no terminal, the service prompt must fail naming the non-interactive form, and write
# nothing - this is the contract automation depends on
echo "+ config version (no tty)"
if out="$("${ROLL_BIN[@]}" config version 2>&1 </dev/null)"; then
>&2 echo "FAIL: roll config version succeeded with no terminal and no arguments"
exit 1
fi
case "${out}" in
*"roll config version <service> <version>"*) ;;
*)
>&2 echo "FAIL: roll config version did not name its non-interactive form"
exit 1
;;
esac

echo "+ config version nosuchservice"
if "${ROLL_BIN[@]}" config version nosuchservice 1.0 >/dev/null 2>&1; then
>&2 echo "FAIL: roll config version accepted an unknown service"
exit 1
fi
)

"$(dirname "$0")/test-syntax.sh"
Expand Down
36 changes: 35 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,41 @@ range. Versions before 0.3.0 predate the GitHub releases and are reconstructed f
Merge commits, automated `Tagged <version>` commits and version bumps are omitted, as are bullets
that only restate the release note above them.

## Unreleased
## Unreleased — 0.8.1

### Added

- **`roll config version` — change a service version interactively.** Prompts for the service, then
for one of the versions that service's image actually has, and writes the pin into `.env.roll`
after taking a timestamped backup. The version list is read from the registry the environment
pulls from (`$ROLL_IMAGE_REPOSITORY`, `ghcr.io/epartment/roll` by default) over the Docker
Registry v2 API and cached for an hour, so it cannot drift from what is publishable. Supplying
both arguments (`roll config version php 8.3`) skips the prompts, and with no terminal the prompt
fails naming that form rather than hanging.
- **`roll config versions`** — the version this project pins for every service, with the key that
holds it and whether the service is enabled. With a service name it lists that service's
published versions, one per line on stdout, for scripting.

### Changed

- **`roll config set` no longer edits `.env.roll` with `sed`.** Both it and the new version picker
go through one writer, which rewrites an existing pin in place, replaces a commented-out one
rather than appending a second line, and passes the value through no pattern expansion — so a
value containing `/` or `&` is written literally instead of corrupting the line. The reported
backup path is now the file that was actually created; it was recomputed from a second `date`
call, so it named a non-existent path whenever the two landed in different seconds.

- **`roll --help` no longer prints the ASCII-art banner.** The usage output now opens on the
version line.

### Fixed

- **`roll --help` and `roll usage` printed the whole help twice.** `commands/usage.help` echoed
`ROLL_USAGE` itself and `commands/usage.cmd` echoed it again after sourcing the file. A `.help`
file only defines `ROLL_USAGE`; rendering belongs to `usage.cmd`. The same stray echo was removed
from `commands/magento2-init.help`.

## [0.8.0](https://github.com/epartment/rolldev/releases/tag/0.8.0) — 2026-09-03

The 0.8.0 development work. Two changes need reading before upgrading — unpinned service versions
now warn (and become an error in 0.9.0), and gum becomes a dependency. Both are covered in
Expand Down
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ environment can produce a fragment set that does not match either copy.

### Dispatch

`bin/roll` is the single entry point. It sources four libraries in a fixed order — `utils/core.sh`,
`utils/config.sh`, `utils/registry.sh`, `utils/env.sh` — verifies Docker and the compose version, then
`bin/roll` is the single entry point. It sources its libraries in a fixed order — `utils/core.sh`,
`utils/interact.sh`, `utils/config.sh`, `utils/images.sh`, `utils/registry.sh`, `utils/env.sh`,
`utils/backup.sh` — verifies Docker and the compose version, then
resolves the first argument through the command registry and **sources** the matching `.cmd` file
(`bin/roll:98`). Sourcing rather than executing is deliberate: every command runs in the same shell
and can use all globals and helper functions without re-deriving them.
Expand Down Expand Up @@ -284,7 +285,8 @@ responsibility is still describable.
|---|---|---|---|
| `bin/roll` | 98 lines | Entry point, dispatch, argument parsing | **Coherent** |
| `utils/core.sh` | 184 lines | Messaging helpers, array/version utilities, network peering | **Coherent** — the three box-drawing functions are one-line wrappers around a shared `box` helper |
| `utils/config.sh` | 606 lines | Config schema, loading, validation, post-processing | **Coherent**; sole owner of configuration defaults |
| `utils/config.sh` | 946 lines | Config schema, loading, validation, post-processing, `.env.roll` writes | **Coherent**; sole owner of configuration defaults |
| `utils/images.sh` | 375 lines | Service catalog (version key, toggle and image per service) and image-tag discovery from the registry | **Coherent** |
| `utils/registry.sh` | 461 lines | Command discovery and priority resolution | **Oversized for what it delivers** — ~200 lines serve `roll registry`'s reporting subcommands; the metadata layer they report on is a stub (**M6**) |
| `utils/env.sh` | 108 lines | Env path location, partial precedence, env-type validation | **Coherent** |
| `utils/install.sh` | 63 lines | Host install assertion, SSH config | **Coherent** |
Expand Down Expand Up @@ -477,6 +479,18 @@ Inspect the resolved configuration for the current project:
roll config show
```

See which version this project pins for every service, and whether that service is enabled:

```bash
roll config versions
```

Change one of them, picking from the versions the image actually has:

```bash
roll config version
```

List every command the registry resolved, including user and third-party packs:

```bash
Expand Down Expand Up @@ -513,6 +527,8 @@ exists and where it lives.
| `roll env up --wait` | Compose native, made meaningful by the healthchecks in `environments/includes/*.base.yml` |
| `roll env doctor` | `commands/doctor.cmd` |
| `roll config check-pins` / `fix-pins` | `commands/config.cmd` |
| `roll config versions [service]` — pinned versions, or a service's published versions one per line on stdout | `commands/config.cmd`, `utils/images.sh` |
| `roll config version <service> <version>` — set a pin without prompting | `commands/config.cmd` |
| Flag-first prompts | `utils/interact.sh` |

Two rules bind anything added here:
Expand Down Expand Up @@ -562,6 +578,9 @@ These are enforced by review rather than by tooling, except where noted.
up with no central list to edit. If it must accept arbitrary pass-through flags, add it to
`ROLL_CMD_ANYARGS` in `bin/roll:43`. Add it to `commands/usage.help` as well — that file is
maintained by hand for visibility.
- **Help files define, they do not print.** A `commands/*.help` file only assigns `ROLL_USAGE`;
`commands/usage.cmd` sources it and does the single `echo -e`. A `.help` file that echoes
`ROLL_USAGE` itself makes the help render twice.
- **Adding a service:** add the fragment(s) under `environments/includes/` (plus per-type overrides),
wire a `ROLL_<SERVICE>` toggle into the assembly block in `commands/env.cmd`, and register the
variable and its default in `initConfigSchema` (`utils/config.sh:58`). Do not rely on a
Expand Down
1 change: 1 addition & 0 deletions bin/roll
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ readonly ROLL_DIR="$(
source "${ROLL_DIR}/utils/core.sh"
source "${ROLL_DIR}/utils/interact.sh"
source "${ROLL_DIR}/utils/config.sh"
source "${ROLL_DIR}/utils/images.sh"
source "${ROLL_DIR}/utils/registry.sh"
source "${ROLL_DIR}/utils/env.sh"
source "${ROLL_DIR}/utils/backup.sh"
Expand Down
Loading
Loading