Pin V8 release manifests and prevent published release replacement (#43444)

## Why

Artifact checksums alone do not authenticate the downloaded checksum manifest. V8 downloads need a trusted digest recorded in the repository, and published releases should not have their assets overwritten.

## What changed

- Pin the V8 `150.4.0` release manifest digests and verify manifests before downloading archives or bindings in packaging and `setup-rusty-v8`, preserving CRLF support.
- Refuse to replace published V8 releases, remove unfinished drafts on retry, and use `gh release create` to upload assets before publication.
- Install Windows `sccache` through a pinned `taiki-e/install-action` in the release and canary workflows.
- Document independent manifest verification and digest recording for version updates.

## Testing

Add five packaging tests covering successful downloads, CRLF manifests, tampered manifests, missing pins, and missing pin files. Rejection tests verify that artifacts are not downloaded.

GitOrigin-RevId: 5c771cdcff376388e124faa4826bf81135d84b50
This commit is contained in:
Charlie Marsh
2026-09-07 11:55:57 +00:00
committed by copyberry
parent 5b85aea979
commit c0b6285711
7 changed files with 250 additions and 52 deletions
+16 -6
View File
@@ -33,11 +33,25 @@ runs:
archive_path="${binding_dir}/${archive_name}"
binding_path="${binding_dir}/${binding_name}"
checksums_path="${binding_dir}/${checksums_name}"
trusted_checksums="${GITHUB_WORKSPACE}/third_party/v8/rusty_v8_${version//./_}_release_manifests.sha256"
if command -v sha256sum >/dev/null 2>&1; then
checksum_command=(sha256sum --check -)
else
checksum_command=(shasum -a 256 --check -)
fi
mkdir -p "${binding_dir}"
curl -fsSL "${base_url}/${checksums_name}" -o "${checksums_path}"
# Check the original manifest bytes even when either checksum file uses CRLF.
expected_manifest_checksum="$(grep -F " ${checksums_name}" "${trusted_checksums}" | cut -d ' ' -f 1)"
actual_manifest_checksum="$(python3 -c 'import hashlib, pathlib, sys; print(hashlib.sha256(pathlib.Path(sys.argv[1]).read_bytes()).hexdigest())' "${checksums_path}")"
if [[ "${actual_manifest_checksum}" != "${expected_manifest_checksum}" ]]; then
echo "Checksum mismatch for ${checksums_name}: expected ${expected_manifest_checksum}, got ${actual_manifest_checksum}" >&2
exit 1
fi
curl -fsSL "${base_url}/${archive_name}" -o "${archive_path}"
curl -fsSL "${base_url}/${binding_name}" -o "${binding_path}"
curl -fsSL "${base_url}/${checksums_name}" -o "${checksums_path}"
if [[ "$(wc -l < "${checksums_path}")" -ne 2 ]]; then
echo "Expected exactly two checksums for ${TARGET} in ${checksums_path}" >&2
@@ -45,10 +59,6 @@ runs:
fi
# Existing Windows-built release manifests use CRLF line endings.
if command -v sha256sum >/dev/null 2>&1; then
(cd "${binding_dir}" && tr -d '\r' < "${checksums_path}" | sha256sum -c -)
else
(cd "${binding_dir}" && tr -d '\r' < "${checksums_path}" | shasum -a 256 -c -)
fi
(cd "${binding_dir}" && tr -d '\r' < "${checksums_path}" | "${checksum_command[@]}")
echo "RUSTY_V8_ARCHIVE=${archive_path}" >> "${GITHUB_ENV}"
echo "RUSTY_V8_SRC_BINDING_PATH=${binding_path}" >> "${GITHUB_ENV}"
+36 -34
View File
@@ -354,22 +354,18 @@ jobs:
restore-keys: |
rusty-v8-source-${{ matrix.target }}-sandbox-
- name: Install and start sccache
- name: Install sccache
uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
with:
tool: sccache@0.8.2
- name: Start sccache
shell: pwsh
env:
SCCACHE_CACHE_SIZE: 256M
SCCACHE_DIR: ${{ github.workspace }}/upstream-rusty-v8/target/sccache
SCCACHE_IDLE_TIMEOUT: 0
run: |
$version = "v0.8.2"
$platform = "x86_64-pc-windows-msvc"
$basename = "sccache-$version-$platform"
$url = "https://github.com/mozilla/sccache/releases/download/$version/$basename.tar.gz"
cd ~
curl -LO $url
tar -xzvf "$basename.tar.gz"
. $basename/sccache --start-server
echo "$(pwd)/$basename" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
run: sccache --start-server
- name: Install Chromium clang for ARM64 MSVC cross build
if: matrix.target == 'aarch64-pc-windows-msvc'
@@ -437,7 +433,6 @@ jobs:
steps:
- name: Check whether release already exists
id: release
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.metadata.outputs.release_tag }}
@@ -445,10 +440,14 @@ jobs:
run: |
set -euo pipefail
if gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" > /dev/null 2>&1; then
echo "exists=true" >> "${GITHUB_OUTPUT}"
else
echo "exists=false" >> "${GITHUB_OUTPUT}"
if is_draft="$(gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" --json isDraft --jq '.isDraft' 2>/dev/null)"; then
if [[ "${is_draft}" != "true" ]]; then
echo "Refusing to replace existing published release ${RELEASE_TAG}." >&2
exit 1
fi
echo "Removing unfinished draft release for ${RELEASE_TAG}."
gh release delete "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" --yes
fi
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -456,22 +455,25 @@ jobs:
path: dist
- name: Create GitHub Release
if: ${{ steps.release.outputs.exists != 'true' }}
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
with:
tag_name: ${{ needs.metadata.outputs.release_tag }}
name: ${{ needs.metadata.outputs.release_tag }}
files: dist/**
# Keep V8 artifact releases out of Codex's normal "latest release" channel.
prerelease: true
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.metadata.outputs.release_tag }}
shell: bash
run: |
set -euo pipefail
assets=()
while IFS= read -r -d '' asset; do
assets+=("${asset}")
done < <(find dist -type f -print0)
if [[ "${#assets[@]}" -eq 0 ]]; then
echo "No V8 release artifacts were found." >&2
exit 1
fi
- name: Amend existing GitHub Release
if: ${{ steps.release.outputs.exists == 'true' }}
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
with:
tag_name: ${{ needs.metadata.outputs.release_tag }}
name: ${{ needs.metadata.outputs.release_tag }}
files: dist/**
overwrite_files: true
# Keep V8 artifact releases out of Codex's normal "latest release" channel.
prerelease: true
# GitHub CLI keeps asset-bearing releases in draft until all uploads finish.
gh release create "${RELEASE_TAG}" \
--repo "${GITHUB_REPOSITORY}" \
--title "${RELEASE_TAG}" \
--verify-tag \
--prerelease \
"${assets[@]}"
+7 -11
View File
@@ -372,22 +372,18 @@ jobs:
restore-keys: |
rusty-v8-source-${{ matrix.target }}-${{ matrix.runner }}-sandbox-
- name: Install and start sccache
- name: Install sccache
uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
with:
tool: sccache@0.8.2
- name: Start sccache
shell: pwsh
env:
SCCACHE_CACHE_SIZE: 256M
SCCACHE_DIR: ${{ steps.setup_ci.outputs.cargo-target-dir }}/sccache
SCCACHE_IDLE_TIMEOUT: 0
run: |
$version = "v0.8.2"
$platform = "x86_64-pc-windows-msvc"
$basename = "sccache-$version-$platform"
$url = "https://github.com/mozilla/sccache/releases/download/$version/$basename.tar.gz"
cd ~
curl -LO $url
tar -xzvf "$basename.tar.gz"
. $basename/sccache --start-server
echo "$(pwd)/$basename" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
run: sccache --start-server
- name: Install Chromium clang for ARM64 MSVC cross build
if: matrix.target == 'aarch64-pc-windows-msvc'