Skip to content

v3.0.0

Latest

Choose a tag to compare

@github-actions github-actions released this 07 Aug 14:26

Changed

  • CI restructured to one workflow per image. build-and-push.yml is replaced by
    image-sf-ci.yml, image-sf-devcontainer.yml, image-sf-bulk.yml and release.yml.
    Path filtering is now GitHub's own on.pull_request.paths rather than a changes job that
    computed a matrix from the PR diff, so the image workflows are inherently parallel and adding
    an image is copying one file. release.yml keeps a matrix because a release must push a
    coherent set and aggregate every image's version report into one GitHub Release — which means
    adding an image now also requires a release.yml matrix entry, or it is tested but never
    published

Added

  • All three images register a second account, runner (UID 1001, GID 0), alongside
    ci/vscode (1000). GitHub Actions container jobs mount /github/home and the runner
    file-command dir owned by the runner's UID, so the job must be that UID to write them —
    and sf crashes on a UID with no /etc/passwd entry, because oclif calls
    os.userInfo(). Registering 1001 statically is what lets the shared Salesforce
    workflows drop options: --user root and run unprivileged. Verified against a
    simulated runner mount, not just a passwd lookup
  • CI: e2e job. On PRs touching sf-ci it retags the already-built image (no rebuild)
    to a throwaway GHCR tag and runs the real weather2gp-release.yml in sf-develop-demo
    against it as --user 1001, synchronously, failing the PR if that pipeline fails.
    Quota-light: no scratch org, and --skip-validation draws on the 500/day pool.
    Needs an E2E_DISPATCH_TOKEN secret with actions: write on the downstream repo
  • sf-devcontainer: openssh-client, so git clone/git push over ssh:// or
    git@host:... remotes work, not just HTTPS. Previously failed with error: cannot run ssh: No such file or directory — the git package doesn't pull it in. Also ships a
    /etc/ssh/ssh_config.d/99-devcontainer.conf setting StrictHostKeyChecking accept-new
    repo-wide, so the first connection to a new host doesn't hang on an unanswerable
    interactive "are you sure? (yes/no)" prompt

Changed — BREAKING

  • sf-ci and sf-bulk now run as non-root ci (UID 1000) at runtime, reverting the
    USER root workaround added in 927c06d. Running CI pipelines as root was the wrong trade.
    Consumers must run the container with UID 1000 — on ARC set the runner pod's
    securityContext.runAsUser: 1000, or add options: --user 1000 to the container job.
    Without that, /github/home (bind-mounted by the runner and owned by its UID) is unwritable
    and the SF CLI fails with EACCES, exactly as before 927c06d. sf-devcontainer was already
    non-root (vscode) and is unchanged. Requires a 3.0.0 release.
    • Writable paths (/home/ci, /opt/sf-data, /opt/sf-config) are now owned by GID 0 and
      group-writable, so any UID that has a passwd entry can write them.
    • Running under an arbitrary UID is explicitly not supported: sf calls Node's
      os.userInfo(), which throws ENOENT when the UID has no /etc/passwd entry. The usual
      entrypoint workaround does not apply — GitHub Actions container jobs override ENTRYPOINT.
  • The reference .devcontainer/devcontainer.json now persists Salesforce org auth in named
    Docker volumes
    (~/.sf, ~/.sfdx) instead of leaving it in the container's throwaway
    layer, so a rebuild no longer costs you a re-login. Do not bind-mount your host's ~/.sf
    or ~/.sfdx
    to share auth: those files are encrypted with the host OS keychain, which a
    Linux container cannot read, and every org then reports AuthDecryptError. Verified
    empirically on 2026-08-06. tests/test_sf_devcontainer.py::test_auth_dirs_not_host_mounted
    guards this repo's own configs against the mistake
  • sf-devcontainer's shell is now Starship with no framework, replacing Oh My Zsh +
    Powerlevel10k. Plugins come from apt instead of git clones; zsh-completions is dropped
    (not packaged for noble). The prompt shows the project's Salesforce target org, read from
    .sf/config.json with jq — never by calling sf, which would add ~500 ms of Node
    startup to every prompt. Anyone relying on OMZ aliases or p10k configure must move that
    into ~/.zshrc.local
  • CI: third-party actions are pinned to floating major tags (@v7, @v4) instead of commit
    SHAs. sigstore/cosign-installer (@v4.1.2) and aquasecurity/trivy-action (@v0.36.0)
    stay exact — neither publishes a floating major tag.

Added

  • CI: path-filtered builds. A changes job reads the PR's changed files and builds only the
    affected images — sf-<image>/** or tests/test_sf_<image>.py selects that image, while
    .github/workflows/**, tests/requirements.txt, or any other tests/*.py rebuilds all of
    them. Docs-only PRs now build nothing. Version tags are unaffected: they always build and
    publish the full set so latest stays coherent across images. The image set is defined once,
    in the IMAGES map of that job. A job summary lists which images were built and which were
    skipped

Removed

  • Superseded design docs: docs/devcontainer-dx-design.md,
    docs/reusable-workflow-migration-design.md, and
    docs/superpowers/specs/2026-07-13-devcontainer-tools-docs-design.md. All three describe work
    that shipped in 2.0.0 and is now documented in CLAUDE.md and the READMEs;
    docs/README.md (the image decision guide) stays

Image tool versions

sf-bulk

Component Version
Node.js v24.18.0
npm 11.16.0
Salesforce CLI @salesforce/cli/2.146.3 linux-x64 node-v24.18.0
Plugin Version
sfdx-git-delta 6.45.1

sf-ci

Component Version
Node.js v24.19.0
npm 11.17.0
Salesforce CLI @salesforce/cli/2.146.3 linux-x64 node-v24.19.0
Plugin Version
sfdx-git-delta 6.45.1

sf-devcontainer

Component Version
Node.js v24.19.0
npm 11.17.0
Salesforce CLI @salesforce/cli/2.146.3 linux-x64 node-v24.19.0
Plugin Version
sfdx-git-delta 6.45.1
@salesforce/plugin-code-analyzer 5.15.0
sfdx-browserforce-plugin 6.3.3

What's Changed

  • Add: own the per-image Docker build workflow instead of calling shared-github-actions by @gambe94 in #13
  • Gate PRs on a real downstream Salesforce release, run unprivileged by @gambe94 in #14
  • feat!: replace Oh My Zsh + Powerlevel10k with Starship, persist devcontainer org auth by @gambe94 in #15

Full Changelog: v2.0.0...v3.0.0