Skip to content

Modernize build/test Dockerfiles: fail-fast scripts, rvm->mise, OpenVox - #925

Merged
silug merged 4 commits into
simp:masterfrom
silug:modernize-build-dockerfiles
Jun 18, 2026
Merged

Modernize build/test Dockerfiles: fail-fast scripts, rvm->mise, OpenVox#925
silug merged 4 commits into
simp:masterfrom
silug:modernize-build-dockerfiles

Conversation

@silug

@silug silug commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

The build-container scripts ran without set -e, so a failing command masked by a later success — or a blanket ||: — let the image build complete as though it had succeeded. The AlmaLinux 8/9/10 Beaker images (ghcr.io/simp/simp-el<N>-beaker) shipped broken this way: redhat-lsb-core does not exist on EL9/10, so its install silently no-op'd and the resulting images were missing packages with no build-time signal.

This PR makes every script fail-fast, modernizes the toolchain (rvm → mise, Puppet → OpenVox, Ruby 3.2/4.0), and adds CI to build and publish the images automatically.

Changes

Reliability

  • Add set -euo pipefail and a purpose/usage header to every script; standardize shebangs to bash.
  • beaker_packages.sh: drop the blanket ||: so a missing package fails the build; remove redhat-lsb-core (retired on EL9/10, unused by the acceptance stack).
  • container_safe_services.sh: guard systemctl daemon-reload, which legitimately fails offline during the image build.
  • user.sh: fix single-quoted sudoers lines that wrote a literal $user_id instead of the username.

Toolchain (build images)

  • Replace rvm with mise. Add per-EL install_mise.sh (EL8 rpm repo, EL9/10 COPR) and a common mise.sh that provisions Ruby 3.2 (OpenVox 8) and 4.0 (OpenVox 9); default selectable via the ruby_version build arg (default 3.2).
  • Pin bundler to 2.7.2 (simp-rake-helpers requires < 3.0).
  • Add libyaml-devel on EL8/EL9 so Ruby's psych extension compiles.
  • Build dockerfiles: default ruby_version=3.2; call install_mise.sh + mise.sh instead of rvm.sh.

CI automation

  • build_container.yml (new) — reusable (workflow_call) workflow that builds one image and optionally pushes it to ghcr.io, tagged latest and a UTC YYYYMMDD date tag so it is clear when an image was built. It only logs into the registry when actually pushing, so fork PRs (read-only GITHUB_TOKEN) still validate cleanly.
  • containers.yml (new) — builds all six images (EL8/9/10 Beaker + Build) via a matrix calling the reusable workflow:
    • Pull requests touching build/Dockerfiles/** build every image without pushing — pre-merge validation that the now-fail-fast scripts make meaningful.
    • Push to master (path-filtered), a weekly schedule (Mondays 06:17 UTC), and manual dispatch build and push to ghcr.io. The schedule keeps images current with upstream base/package updates even when the Dockerfiles are unchanged.
  • build_containers.yml — refactored to call the reusable workflow; retained for ad-hoc single-image rebuilds (specific Ruby version, git ref, or extra tag).

Docs

  • README: document the two image families (Beaker SUT vs. ISO build) and a per-script purpose table; reframe build args around OpenVox; fix the stale Dockerhub → ghcr.io note.
  • AGENTS.md: document the three container workflows.

Bugs surfaced by fail-fast (would have shipped broken before)

Because the scripts now abort on error, building the Build images locally exposed two real problems the old silent scripts hid:

  1. Ruby wouldn't compile — EL8/EL9 installed libyaml but not libyaml-devel, so the psych extension failed (no yaml.h). Fixed by adding libyaml-devel.
  2. Bundler too new — without rvm's old pin, mise installed bundler 4.x, which simp-rake-helpers (< 3.0) rejects. Pinned to 2.7.2 (matches simp-core's Gemfile.lock).

Testing

All six images built and smoke-tested locally with podman build (AlmaLinux 8/9/10):

Image Build Verified
simp-el{8,9,10}-beaker baseline packages present, container_safe_services unit enabled, redhat-lsb-core correctly absent
simp-el{8,9,10}-build Ruby 3.2.11 default + 4.0.5 via mise, bundler 2.7.2, simp-core bundle satisfied

The CI workflows were validated with actionlint (clean).

Notes for reviewers

  • The EL8 mise repo URL is https://mise.en.dev/rpm/mise.repo, taken from the official mise docs; it resolves as a mirror of mise.jdx.dev (GPG key release@mise.jdx.dev). EL9/10 use the jdxcode/mise COPR.
  • The Beaker images are unchanged toolchain-wise (no Ruby) — only the reliability/packaging fixes apply to them. They ignore the ruby_version build arg (Docker emits a harmless "build-arg not consumed" warning).

silug and others added 2 commits June 17, 2026 21:38
The build-container scripts ran without `set -e`, so a failing command
masked by a later success (or a blanket `||:`) let the build complete as
though it had succeeded. The AlmaLinux 8/9/10 Beaker images shipped broken
this way (e.g. redhat-lsb-core does not exist on EL9/10 and silently
no-op'd). Make every script fail-fast and modernize the toolchain.

Reliability:
- Add `set -euo pipefail` and a purpose/usage header to every script;
  standardize shebangs to bash.
- beaker_packages.sh: drop the blanket `||:` so a missing package fails
  the build; remove redhat-lsb-core (retired on EL9/10, unused).
- container_safe_services.sh: guard `systemctl daemon-reload`, which
  legitimately fails offline during the image build.
- user.sh: fix single-quoted sudoers lines that wrote a literal
  "$user_id" instead of the username.

Toolchain (build images):
- Replace rvm with mise. Add per-EL install_mise.sh (EL8 rpm repo, EL9/10
  COPR) and common mise.sh provisioning Ruby 3.2 (OpenVox 8) and 4.0
  (OpenVox 9); default 3.2 via the ruby_version build arg.
- Pin bundler to 2.7.2 (simp-rake-helpers requires < 3.0).
- Add libyaml-devel on EL8/EL9 so Ruby's psych extension compiles.
- Build dockerfiles: default ruby_version=3.2; call install_mise.sh +
  mise.sh instead of rvm.sh.

Docs/CI:
- README: document the two image families and per-script purpose table;
  reframe build args around OpenVox; fix stale Dockerhub -> ghcr.io note.
- build_containers.yml: Ruby choices 2.7/3.1/3.3 -> 3.2/4.0, default 3.2.

All six images (EL8/9/10 Beaker + Build) build and smoke-test clean
locally with podman.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add CI to build the build/Dockerfiles images automatically, complementing
the existing manual workflow.

- build_container.yml: new reusable (workflow_call) workflow that builds one
  image and optionally pushes it to ghcr.io, tagged `latest` and a UTC
  `YYYYMMDD` date tag so it is clear when an image was built.
- containers.yml: builds all six images (EL8/9/10 Beaker + Build) via a
  matrix. Pull requests touching the Dockerfiles build without pushing
  (pre-merge validation, which the fail-fast scripts make meaningful);
  push to master (path-filtered), a weekly schedule, and manual dispatch
  build and push. The schedule keeps images current with upstream updates.
- build_containers.yml: refactored to call the reusable workflow; retained
  for ad-hoc single-image rebuilds (specific Ruby version, ref, extra tag).
- AGENTS.md: document the three container workflows.

Validated with actionlint (clean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the SIMP build/test container infrastructure by making build scripts fail-fast, replacing RVM with mise for Ruby provisioning, updating the default Ruby/toolchain expectations for OpenVox, and adding CI workflows to validate and publish container images built from build/Dockerfiles/.

Changes:

  • Switch ISO build images from rvm.sh to per-EL install_mise.sh + common mise.sh, and bump default ruby_version to 3.2.
  • Make container build scripts consistent and fail-fast (bash + set -euo pipefail), and fix Beaker/base package installation behavior.
  • Add/reshape GitHub Actions workflows to build all images on relevant PRs and publish them on push/schedule/manual runs.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
build/Dockerfiles/SIMP_EL8_Build.dockerfile Default Ruby build arg to 3.2 and switch Ruby provisioning to mise.
build/Dockerfiles/SIMP_EL9_Build.dockerfile Default Ruby build arg to 3.2 and switch Ruby provisioning to mise.
build/Dockerfiles/SIMP_EL10_Build.dockerfile Default Ruby build arg to 3.2 and switch Ruby provisioning to mise.
build/Dockerfiles/scripts/el8/install_mise.sh Install mise system-wide on EL8 via upstream repo.
build/Dockerfiles/scripts/el9/install_mise.sh Install mise system-wide on EL9 via COPR.
build/Dockerfiles/scripts/el10/install_mise.sh Install mise system-wide on EL10 via COPR.
build/Dockerfiles/scripts/el8/00_system_prep.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el9/00_system_prep.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el10/00_system_prep.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el8/00_setup_vault.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el9/00_setup_vault.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el10/00_setup_vault.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el8/05_selinux.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el9/05_selinux.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el10/05_selinux.sh Standardize script header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/el8/10_dev_packages.sh Add libyaml-devel and standardize script header/fail-fast behavior.
build/Dockerfiles/scripts/el9/10_dev_packages.sh Add libyaml-devel and standardize script header/fail-fast behavior.
build/Dockerfiles/scripts/el10/10_dev_packages.sh Standardize script header/fail-fast behavior (and includes libyaml-devel).
build/Dockerfiles/scripts/common/rvm.sh Remove legacy RVM-based Ruby provisioning script.
build/Dockerfiles/scripts/common/mise.sh New: provision Ruby via mise and pin bundler version.
build/Dockerfiles/scripts/common/user.sh Standardize header/fail-fast behavior and fix sudoers variable expansion.
build/Dockerfiles/scripts/common/prime_ruby.sh Standardize header/fail-fast behavior and tighten quoting/commands.
build/Dockerfiles/scripts/common/minimize_package_installs.sh Add header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/common/package_cleanup.sh Add header and enforce fail-fast shell settings.
build/Dockerfiles/scripts/common/container_safe_services.sh Add header and guard systemctl daemon-reload during image build.
build/Dockerfiles/scripts/common/beaker_packages.sh Make Beaker package installs fail-fast and drop redhat-lsb-core.
build/Dockerfiles/README.md Document image families, scripts, and mise/OpenVox-focused build args.
AGENTS.md Update CI workflow documentation to include new container workflows.
.github/workflows/containers.yml New: build all Dockerfiles on relevant PRs; publish on push/schedule/manual runs.
.github/workflows/build_container.yml New reusable workflow to build/push a single image with consistent tagging.
.github/workflows/build_containers.yml Refactor manual workflow to call the reusable build workflow and update Ruby choices.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build/Dockerfiles/scripts/common/mise.sh
Comment thread build/Dockerfiles/scripts/common/user.sh Outdated
silug and others added 2 commits June 18, 2026 16:28
Two fixes from PR review:

- mise.sh: always install both supported Rubies (3.2 + 4.0) and reject any
  ruby_version other than 3.2/4.0, instead of letting an unexpected value
  drop Ruby 3.2 and fail the later `mise exec ruby@3.2` bundler install.
  The build arg now only selects which Ruby is the global default.
- user.sh: write sudo config to a 0440 /etc/sudoers.d/<user> drop-in
  (idempotent across rebuilds) and validate it with `visudo -cf` instead
  of appending to /etc/sudoers, so a malformed line can't break sudo for
  the whole image. sudo is installed in 05_selinux.sh, before user.sh.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The static workflow name "Containers: build + publish" mislabeled PR runs,
which build images but never publish them (push: false on pull_request).

- Rename the workflow to the neutral "Containers" and add a dynamic run-name
  that reads "build (no publish)" on PRs and "build + publish" otherwise.
- Rename the caller job containers -> build so the PR check reads
  "Containers / build / <image>" instead of "containers / containers".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@silug
silug merged commit cffb38f into simp:master Jun 18, 2026
10 checks passed
@silug
silug deleted the modernize-build-dockerfiles branch June 18, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants