Skip to content

Build complete AMD64 and ARM64 Railpack images - #833

Merged
nick-potts merged 13 commits into
mainfrom
t3code/implement-805
Sep 9, 2026
Merged

nick-potts merged 13 commits into
mainfrom
t3code/implement-805

Conversation

@nick-potts

@nick-potts nick-potts commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Closes #805.

Railpack 0.39.0 rejects a combined platform solve. Explicit build.platforms: [linux/amd64, linux/arm64] now runs separate solves inside one Build Attempt, assembles an OCI index with pinned regctl, and loads and verifies each platform's content in Docker's containerd store. Results use the Docker content digest, so they remain usable after every requested tag moves.

Worker capability checks precede compilation. The CLI owns cancellation across build and subsequent command phases; the build library borrows cancellation without installing process signal handlers. A shared scoped container operation owns creation and cleanup, including ambiguous create failures, and treats confirmed absence as successful cleanup. Output failures retain their stage, and completed image evidence survives a later cleanup failure.

Native defaults remain available; Dockerfiles stay single-platform and multi-platform Railpack output is local. Requested multi-platform build.provenance and build.sbom are rejected during capture because assembly cannot preserve them; explicit false and single-platform attestations remain supported. The README links the immutable prototype findings and their evidence limits. Includes the host resource/cache policy from main and preserves remote admission, progress evidence, cancellation, and scoped preparation cleanup.

Validation:

  • cargo fmt --all -- --check and workspace Clippy with all targets/features and -D warnings.
  • cargo test --workspace --all-features --locked -j 4 — passed on the final commit using the default build directory.
  • Rung 1: build-library and CLI unit regressions cover default signals after library execution, cancellation across command phases, and cancellation during prompts.
  • Rung 2: cargo test -p ployz --test build --locked — 29 tests, including provenance/SBOM rejection, missing content, solve/assembly/import failures, tag reuse, absent and ambiguous container creation, cancellation with failed cleanup, and completed image evidence after cleanup failure.
  • Rung 3: compose CLI and remote build CLI checks.
  • Rung 4: cargo test -p ployz --test build_layer3 railpack_builds_complete -- --ignored --nocapture — both variants run with --pull never after all requested tags move; independent inventory checks verify the index, manifests, configurations, and every layer hash. AMD64 was native and ARM64 was emulated with QEMU; this is not native ARM64 or release Authority proof.

Reviews: Standards PASS; Spec PASS; Maintainability PASS; Simplicity PASS.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-09T04:11:22.594495Z 18a5b06 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6528bdaa0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/ployz-build/src/cancellation.rs Outdated
impl Drop for Cancellation {
fn drop(&mut self) {
for signal in &self.signals {
signal_hook::low_level::unregister(*signal);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore termination handling after the build

Dropping Cancellation unregisters the last signal-hook actions, but signal-hook does not restore the prior/default disposition when its final action is removed; subsequent SIGINT/SIGTERM signals are therefore ignored. This affects flows that continue after building, notably ployz deploy and ployz build --push, whose runtime is created only after execute returns: a SIGTERM during the potentially long push/deploy phase will no longer terminate the command. Keep an appropriate termination action installed or explicitly restore/emulate the previous disposition instead of unregistering these handlers during normal runtime.

Useful? React with 👍 / 👎.

Comment thread crates/ployz-build/src/index.rs Outdated
Streams::Captured,
) {
Ok(_) => result,
Err(error) => Err(BuildError::UncertainTermination(error.to_string())),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the error when no assembly container exists

If cancellation is observed before docker create starts, or creation fails before producing a container, result contains the real cancellation/create error but the final docker rm --force reports “No such container”; this branch replaces that useful diagnosis with UncertainTermination even though absence confirms cleanup. The equivalent cleanup in railpack::prepare_container already treats this response as success, so assembly cleanup should preserve result in the same case.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2f2787c7f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

for setting in [
format!("{}.platform={platform}", target.bake),
format!("{}.output=type=oci,dest={}", target.bake, archive.display()),
format!("{}.attest=type=provenance,disabled=true", target.bake),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve requested provenance in multi-platform builds

When a Railpack service requests multiple platforms with build.provenance: true, the capture layer explicitly accepts that setting (crates/ployz/src/compose/build.rs:337-355), but this unconditional command-line override disables provenance for every solve. The build then succeeds while silently omitting requested attestations, unlike the single-platform path; either preserve provenance through index assembly or reject the option for multi-platform Railpack builds.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bfa2aefeae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

for setting in [
format!("{}.platform={platform}", target.bake),
format!("{}.output=type=oci,dest={}", target.bake, archive.display()),
format!("{}.attest=type=provenance,disabled=true", target.bake),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve SBOM in multi-platform Railpack solves

For a Railpack service with platforms: [linux/amd64, linux/arm64] and sbom: true, capture still accepts the SBOM option, but this --set <target>.attest=type=provenance,disabled=true replaces Bake's attestation list and silently removes the requested SBOM from each solve. The final tree now rejects requested provenance for this path but has no equivalent SBOM guard, so either reject non-false build.sbom for multi-platform Railpack builds or preserve it with an additive attestation override.

AGENTS.md reference: AGENTS.md:L3-L3

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6f50260fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +166 to +169
if build.get(field).is_some_and(|value| {
!matches!(value, Value::Null | Value::Bool(false))
&& value.as_str() != Some("false")
}) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove false attestations before remote validation

For a remote multi-platform Railpack build with provenance: false or sbom: false, this branch admits the value and leaves the key in the captured Compose file. execute_remote then calls remote::validate_capture (crates/ployz/src/compose/remote_build.rs:25), whose build allowlist (crates/ployz-build/src/received_recipe.rs:60-82) contains neither key, so the request is rejected as unsupported remote build.<field> before upload. Either remove explicitly false attestation fields during capture or allow and validate them at the remote boundary.

Useful? React with 👍 / 👎.

@nick-potts
nick-potts merged commit e6f95cd into main Sep 9, 2026
7 checks passed
@nick-potts
nick-potts deleted the t3code/implement-805 branch September 30, 2026 15:15
nick-potts added a commit that referenced this pull request Sep 30, 2026
* feat(build): produce complete AMD64 and ARM64 Railpack images

* Make build cancellation caller-owned and scope helper container cleanup

* Preserve assembled image evidence and output failure stages

* Reject unsupported provenance for multi-platform Railpack builds

* Isolate cancellation fixtures under host build ownership

* Report local Docker context in signal regression fixture

* Reject unsupported SBOM requests for multi-platform Railpack

* Normalize disabled multi-platform attestations before remote validation

---------

Co-authored-by: Codex <codex@codex-vm.tailcb9c5.ts.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.

Build a complete AMD64 and ARM64 Railpack image

1 participant