Skip to content

Use docker actions for buildx caching and secure login#43

Merged
baelter merged 7 commits intoheroku-container-workflowfrom
container-build-and-push
Mar 11, 2026
Merged

Use docker actions for buildx caching and secure login#43
baelter merged 7 commits intoheroku-container-workflowfrom
container-build-and-push

Conversation

@dentarg
Copy link
Contributor

@dentarg dentarg commented Mar 11, 2026

● Changes:

  1. docker/login-action@v3 — secrets passed via with: instead of shell expansion, avoiding secret exposure in process lists
  2. docker/setup-buildx-action@v3 — enables BuildKit with GHA layer caching
  3. docker buildx build --push --cache-from type=gha --cache-to type=gha,mode=max — build + push in one step with cross-run layer caching
  4. Removed the standalone docker build --target build warmup — the GHA cache handles shared layer reuse across targets automatically

The reason we still use docker buildx build in a shell loop rather than docker/build-push-action directly: targets are dynamic (space-separated input), and
you can't loop over an action step. docker buildx build is the same engine underneath, so caching works identically.

Replace raw docker login with docker/login-action for secure secret
handling, add docker/setup-buildx-action for BuildKit with GHA layer
caching, and switch to docker buildx build --push with cache flags.
Removes the standalone --target build warmup step since the GHA cache
handles shared layer reuse across targets.
dentarg added 5 commits March 11, 2026 16:53
Single docker buildx build with multiple -t flags instead of building
per target. Rename targets input to process-types to reflect what they
actually are (Heroku process types, not Dockerfile targets).
Construct build-args as a multiline step output instead of mixing
expressions with YAML block scalars. Add context: . to use the local
checkout instead of git context.
@dentarg dentarg force-pushed the container-build-and-push branch from 0d97cb9 to 9276d6a Compare March 11, 2026 17:48
Heroku's container registry doesn't support OCI manifest lists that
buildx creates when provenance attestations are enabled.
@baelter baelter merged commit fdf43b2 into heroku-container-workflow Mar 11, 2026
5 checks passed
@baelter baelter deleted the container-build-and-push branch March 11, 2026 18:08
@dentarg dentarg restored the container-build-and-push branch March 11, 2026 18:12
@dentarg
Copy link
Contributor Author

dentarg commented Mar 11, 2026

@baelter I am actively (well, have to go very soon) testing this :) I haven't gotten successful deploy yet

baelter pushed a commit that referenced this pull request Mar 17, 2026
* Use docker actions for buildx caching and secure login

Replace raw docker login with docker/login-action for secure secret
handling, add docker/setup-buildx-action for BuildKit with GHA layer
caching, and switch to docker buildx build --push with cache flags.
Removes the standalone --target build warmup step since the GHA cache
handles shared layer reuse across targets.

* Build once and push to all process types

Single docker buildx build with multiple -t flags instead of building
per target. Rename targets input to process-types to reflect what they
actually are (Heroku process types, not Dockerfile targets).

* Pass RUBY_VERSION build arg from .ruby-version file if present

* Bump actions so Node.js 24 is used

https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

* Use docker/build-push-action instead of shell docker buildx build

* Fix build-args passing and add context to build-push-action

Construct build-args as a multiline step output instead of mixing
expressions with YAML block scalars. Add context: . to use the local
checkout instead of git context.

* Disable provenance attestation for Heroku registry compatibility

Heroku's container registry doesn't support OCI manifest lists that
buildx creates when provenance attestations are enabled.
baelter added a commit that referenced this pull request Mar 17, 2026
* Add shared workflow for Heroku container deploys

Builds Docker images in CI and pushes to Heroku's container registry.
Companion to heroku.yml (git-push) for repos using container stack.

Inputs: heroku-app, branch, targets (Dockerfile build targets)
Secrets: heroku-key, build-args (for private dependency auth)

* Use docker actions for buildx caching and secure login (#43)

* Use docker actions for buildx caching and secure login

Replace raw docker login with docker/login-action for secure secret
handling, add docker/setup-buildx-action for BuildKit with GHA layer
caching, and switch to docker buildx build --push with cache flags.
Removes the standalone --target build warmup step since the GHA cache
handles shared layer reuse across targets.

* Build once and push to all process types

Single docker buildx build with multiple -t flags instead of building
per target. Rename targets input to process-types to reflect what they
actually are (Heroku process types, not Dockerfile targets).

* Pass RUBY_VERSION build arg from .ruby-version file if present

* Bump actions so Node.js 24 is used

https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

* Use docker/build-push-action instead of shell docker buildx build

* Fix build-args passing and add context to build-push-action

Construct build-args as a multiline step output instead of mixing
expressions with YAML block scalars. Add context: . to use the local
checkout instead of git context.

* Disable provenance attestation for Heroku registry compatibility

Heroku's container registry doesn't support OCI manifest lists that
buildx creates when provenance attestations are enabled.

* Build per process type to get correct CMD per image

Single-build-multiple-tag pushed the same image (same CMD) to all
process types, causing e.g. worker to start Puma instead of its own
command. Build with --target per process type so each image gets the
CMD from its Dockerfile stage.

* Remove Ruby-specific RUBY_VERSION logic from shared workflow

The shared workflow should be language-agnostic. Repos that need
RUBY_VERSION can pass it via build-args in their own deploy workflow.

* Add standalone deploy script for when GitHub Actions is unavailable

Same build logic as the workflow but without GHA-specific bits (layer
caching, login-action). Run from a developer machine with docker,
heroku CLI, and HEROKU_API_KEY.

* Auto-detect .*-version files as build args

Scans for .*-version files (e.g. .ruby-version, .node-version) after
checkout and passes them as --build-arg flags. This lets Dockerfiles
use ARG RUBY_VERSION (or similar) without callers having to explicitly
pass the version.

* Harden workflow security and fix shell quoting

- Pin actions to SHA hashes (checkout, login-action, setup-buildx)
- Fix template injection: move inputs/context to env vars
- Use jq --arg for safe JSON construction
- Convert build_arg_flags from string to bash array
- Map cancelled job status to error for deployment API
- Guard deployment status step on DEPLOYMENT_ID existence
- Add persist-credentials: false to checkout

---------

Co-authored-by: Patrik Ragnarsson <patrik@starkast.net>
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.

2 participants