Skip to content

Latest commit

 

History

History
168 lines (116 loc) · 8.1 KB

File metadata and controls

168 lines (116 loc) · 8.1 KB

Maintainer guide

This guide covers common maintenance tasks shared across the Posit container image repositories (images-connect, images-workbench, images-package-manager). For product-specific context, examples, and CI workflow details, see CONTRIBUTING.md in the product repository.

Add a version

The product-release.yml workflow creates versions automatically when a product releases. For hotfixes or when the dispatch fails, use the bakery CLI directly.

See Step 3: Create an image version in the bakery getting-started guide for the full command reference.

The product-release.yml shared workflow handles automatic releases:

  • If the version's edition (e.g., 2026.05) already exists in bakery.yaml, it patches it with bakery update version.
  • If the edition is new, it creates it with bakery create version, marking it --mark-latest if it is newer than the current latest edition.

After any version create or update, re-render templates:

bakery update files --image-name <name> --image-version <edition>

Add an image

Adding an image means a new entry in bakery.yaml and a new template/ directory. Follow the existing images in the repo as your model.

See Step 2: Create an image for the full bakery CLI walkthrough.

When a new image name is added:

  • Update the relevant CI caller workflows to include it in the build scope.
  • Add goss tests in template/test/goss.yaml.jinja2.
  • If the image pushes to a separate registry namespace, add a registry entry in bakery.yaml.
# Scaffold the image entry and template directory
bakery create image <image-name>

Update dependencies

Bakery resolves dependency versions (Python, R, Quarto) at build time using dependencyConstraints in bakery.yaml. A constraint of latest: true causes bakery to query upstream registries for the current latest compatible version.

See DependencyConstraint in the configuration reference for the full schema.

To pin a specific version instead of tracking latest, replace the constraint with an explicit dependencyVersions list for the relevant image version. See DependencyVersions.

UV availability: see Footguns before adding a new Python minor version.

Update older versions

Update older versions when a base image or system package receives a Common Vulnerabilities and Exposures (CVE) fix, or when a shared template change needs to apply retroactively.

Procedure

  1. Edit the template in template/. Never edit the rendered file in the version directory.

  2. Re-render: bakery update files --image-name <name> --image-version <edition>.

  3. Build and test locally:

    bakery build --image-name <name> --image-version <edition>
    bakery dgoss run --image-name <name> --image-version <edition>
  4. Open a pull request (PR) that includes both the template change and the re-rendered version directory.

Do not backport cosmetic changes, new feature additions, or non-security dependency upgrades. Backports increase maintenance surface. Reserve them for security fixes and regressions.

Footguns

  • Never edit rendered files. Files in version directories (e.g., <image>/<edition>/Containerfile.<os>.<variant>) are generated from templates. bakery update files silently overwrites any edits there. Always edit the template/ files.

  • Never work directly on main. Multiple CI sessions may be running concurrently. Use a branch. For changes spanning multiple repos, use a git worktree per repo so each change is isolated from main.

  • Python version not yet in UV. When a new CPython minor version is released, there is a lag before UV's managed Python manifest includes it. bakery build fails with a uv python install error. Check UV's download-metadata.json to confirm availability before adding the version.

  • Stale UV base image cache. Even after UV upstream adds a new Python version, a cached builder layer from a previous run might not know about it. If a build fails on uv python install despite the version being in the manifest, clear the cache:

    bakery clean cache-registry ghcr.io/posit-dev

    The clean.yml workflow removes caches older than 14 days on a schedule.

  • Version format mismatch. Product repos dispatch with raw git-describe versions (e.g., v2026.03.0-473-g072bb6fd1f). Bakery normalizes these to semver-with-metadata (e.g., 2026.03.0-dev+473-g072bb6fd1f). If bakery ci matrix produces an empty matrix after a dispatch, the formats did not align. The shared workflows strip a leading v automatically. Check the rest of the version string against bakery's normalization.

Change-aware PR builds

bakery ci matrix supports --base-ref <ref> and --changed-files-from <file|-> to emit only the matrix entries affected by a PR's changed files. This keeps PR CI fast: a template change builds only the images whose templates changed; a version-directory change builds only that version.

This filtering applies to PR builds only. Push-to-main, scheduled, and release builds call bakery ci matrix without --base-ref, so they always build the full matrix.

Classification rules

After ignoring Markdown (*.md) paths, changed files are classified as follows:

Changed path What builds
bakery.yaml / bakery.yml or .github/workflows/** Full matrix (fail-safe)
<image>/template/** That image's dev versions (if any are declared)
<image>/<version-subpath>/** That release version only
An image-root file or unrecognized subdir under an image That image's release versions (fail-safe)
Matrix image (e.g. connect-content) Latest matrix slice + dev versions if declared
Anything else not attributable and not ignored Full matrix (fail-safe)

Branch protection

Because per-image build jobs may not run on docs-only PRs, branch protection rules should require the always-green Build/Test result gate job rather than individual build jobs. The gate job is defined in bakery-build-pr.yml and always runs, even when no images need to be built.

Diagnose a build failure

1. Find the failing run:

gh run list -R posit-dev/<product-repo>

2. View the run to see which job failed (matrix, build-amd64, build-arm64, merge, readme):

gh run view <run-id> -R posit-dev/<product-repo>

3. Read the failed logs:

gh run view <run-id> -R posit-dev/<product-repo> --log-failed

4. Common failure modes:

Failure Symptom Fix
Python version not in UV uv python install fails — "no managed Python" Check UV's download-metadata.json; wait or pin
Stale UV cache Same error but version is in manifest bakery clean cache-registry ghcr.io/posit-dev
Goss test timeout Container exits before goss probes Increase wait: in the image's options block in bakery.yaml
Registry auth Login step fails Check DOCKER_HUB_ACCESS_TOKEN (Docker Hub) or AWS_ROLE + id-token: write (Amazon ECR)
ARM64 runner unavailable build-arm64 job queued but never starts Re-run the job; capacity usually clears
Empty matrix after dispatch bakery ci matrix returns [] Dispatched version format didn't match bakery normalization; inspect image-version input
Dev build pushed without -preview Release version matches current daily dev-channel version Known issue (#553); check bakery ci merge inputs

For the shared workflow reference (inputs, secrets, flow diagrams), see CI.md. For the cross-repo dispatch chain, see CI_CROSS_REPO_WORKFLOWS.md.