Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Make --rust-image-digest optional for build_image.py - #29

Open
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags
Open

Make --rust-image-digest optional for build_image.py#29
ethanfrey wants to merge 3 commits into
stellar:mainfrom
vrfier:simpler-cli-flags

Conversation

@ethanfrey

Copy link
Copy Markdown
Contributor

Pasting in a 64-char sha256 every single time you run the build command is annoying — and honestly kind of pointless, since most of the time the digest is already implied by the other args you're passing.

builds.json is already the source of truth of the (stellar-cli, rust base) pairs we publish, and every rust base is pinned as a full <label>@<digest>. In the common case, a given cli version only declares a rust version once, so --stellar-cli-version + --rust-version already pin down the digest completely. Making you copy-paste it on top of that doesn't buy any safety, it just gives you one more chance to fat-finger a hash.

The digest only actually tells us something when the same rust version shows up with more than one digest (say, a relabelled or refreshed base). So that's the only case where the flag is still required now. The updated behavior looks like:

  • Omitted + rust version is unambiguous: script resolves the digest from builds.json for you.
  • Omitted + ambiguous: script fails loudly and list the candidate digests, so you know exactly what to pass.
  • Undeclared rust version: still errors, same as before.
  • Explicit rust image digest passed: still asserts that exact pin is declared, same as before.

So nothing's been loosened — we've just dropped a required argument in the one case where the data already knew the answer.

CopilotAI review requested due to automatic review settings June 10, 2026 10:49

CopilotAI 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

Note

Copilot was unable to run its full agentic suite in this review.

Adds automatic resolution of the Rust base image digest (from builds.json) when the selected Rust label maps to a single declared digest, making --rust-image-digest optional and only required for ambiguous labels.

Changes:

  • Introduce builds.resolve_rust_digest() to validate/resolve digests for (stellar-cli version, rust label) selections.
  • Update build_image.py CLI to make --rust-image-digest optional and use the new resolver.
  • Add unit tests and update docs to reflect the new default behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
tests/unit/test_builds.pyAdds unit tests for digest resolution behavior (implicit, explicit, ambiguous, undeclared).
tests/unit/test_build_image.pyAdds CLI-level tests for inferred digest and failure on ambiguity without digest.
scripts/lib/builds.pyImplements digest resolution logic for rust base pins.
scripts/build_image.pyMakes --rust-image-digest optional and resolves digest from builds data.
RELEASE.mdUpdates release/build instructions to reflect optional digest selection.
README.mdUpdates local build documentation to reflect automatic digest resolution.

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

Comment threadscripts/lib/builds.py Outdated
Comment on lines +98 to +103
entry = find_cli(data, cli)
pins = [pin for pin in (entry or {}).get("rust_versions", []) if label_of(pin) == label]
if not pins:
raise ValueError(
f"stellar-cli {cli} is not declared with rust base {label} in builds.json"
)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadscripts/lib/builds.py Outdated
Comment on lines +94 to +96
if digest:
assert_pair_declared(data, cli, f"{label}@{digest}")
return digest

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

Comment threadtests/unit/test_build_image.py Outdated

assert rc == 0
args = captured.call_args[0][0]
assert f"RUST_IMAGE_DIGEST={DIGEST}" in args

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Fixed in 3f512ae

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:b8f6ee6a97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 44 to 47
./scripts/smoke_test_image.py \
--image "${{ steps.pair.outputs.image }}" \
--stellar-cli-version "${{ steps.pair.outputs.cli }}" \
--rust-version "${{ steps.pair.outputs.rust }}" \

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 Keep passing the digest to smoke_test_image.py

In the build workflow that is invoked by .github/workflows/ci.yml, this smoke-test command now omits --rust-image-digest, but scripts/smoke_test_image.py still declares that option as required in build_parser(). As soon as CI reaches this step, argparse exits with a missing-argument error before any smoke checks run, so the build job fails even for valid images; either keep passing ${{ steps.pair.outputs.digest }} here or make the smoke script resolve it too.

Useful? React with 👍 / 👎.

Sign up for freeto 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

@ethanfrey