Adopt pinned public core snapshot and prepare Sized 2.0.0
This commit is contained in:
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify the exact public core snapshot without contacting its private forge."""
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
pin = json.loads((root / 'CORE-SNAPSHOT.json').read_text())
|
||||
snapshot = root / 'crates/sized-core'
|
||||
actual = {str(p.relative_to(snapshot)): hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
for p in snapshot.rglob('*') if p.is_file()}
|
||||
if actual != pin['files']:
|
||||
raise SystemExit('Core snapshot differs from CORE-SNAPSHOT.json; review the upstream pin and every changed file.')
|
||||
print(f"Core snapshot verified: {pin['revision']} ({len(actual)} files)")
|
||||
@@ -12,16 +12,22 @@ cargo --version
|
||||
check_root=$(mktemp -d /tmp/sized-check.XXXXXX)
|
||||
source_root=${SIZED_TEST_SOURCE:-/source}
|
||||
cp "$source_root/Cargo.toml" "$source_root/Cargo.lock" "$check_root/"
|
||||
cp -R "$source_root/src" "$source_root/tests" "$source_root/benches" "$check_root/"
|
||||
cp -R "$source_root/src" "$source_root/tests" "$source_root/benches" "$source_root/crates" "$source_root/docs" "$check_root/"
|
||||
cp "$source_root/CORE-SNAPSHOT.json" "$check_root/"
|
||||
if [[ -d "$source_root/vendor" ]]; then
|
||||
cp -R "$source_root/vendor" "$source_root/.cargo" "$check_root/"
|
||||
export CARGO_NET_OFFLINE=true
|
||||
fi
|
||||
cp "$source_root/LICENSE" "$source_root/README.md" "$source_root/MANUAL.md" "$check_root/"
|
||||
mkdir "$check_root/scripts"
|
||||
cp "$source_root/scripts/release.sh" "$source_root/scripts/check-release.sh" "$check_root/scripts/"
|
||||
export SIZED_SOURCE_REVISION="$(git -C "$source_root" rev-parse HEAD 2>/dev/null || printf unknown)"
|
||||
cp "$source_root"/scripts/{release.sh,check-release.sh,check-core.py,package-notices.py} "$check_root/scripts/"
|
||||
export SIZED_SOURCE_REVISION="${SIZED_SOURCE_REVISION:-$(git -C "$source_root" rev-parse HEAD 2>/dev/null || printf unknown)}"
|
||||
cd "$check_root"
|
||||
python3 scripts/check-core.py
|
||||
cargo fmt --all -- --check
|
||||
cargo test --locked
|
||||
cargo test --locked --test linux_mount -- --ignored
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
cargo test --locked --workspace
|
||||
cargo test --locked --workspace --test linux_mount -- --ignored
|
||||
cargo clippy --locked --workspace --all-targets -- -D warnings
|
||||
cargo build --locked --release
|
||||
|
||||
fixture_root=$(mktemp -d /tmp/sized-release.XXXXXX)
|
||||
@@ -29,4 +35,7 @@ printf 'Linux release smoke test\n' > "$fixture_root/payload"
|
||||
./target/release/sized --version
|
||||
./target/release/sized "$fixture_root" --threads 2 --one-file-system --apparent --format json
|
||||
./scripts/check-release.sh
|
||||
if [[ -n ${SIZED_RELEASE_DIR:-} ]]; then
|
||||
./scripts/release.sh --output-dir "$SIZED_RELEASE_DIR/sized-v2.0.0-$(rustc -vV | sed -n 's/^host: //p')"
|
||||
fi
|
||||
printf 'Linux checks passed.\n'
|
||||
|
||||
@@ -7,7 +7,7 @@ trap 'rm -rf "$check_root"' EXIT
|
||||
"$repo_root/scripts/release.sh" --output-dir "$check_root/bundle"
|
||||
mkdir "$check_root/extracted" "$check_root/fixture"
|
||||
tar -xzf "$check_root/bundle.tar.gz" -C "$check_root/extracted"
|
||||
for required in sized sized.1 sized.bash _sized sized.fish LICENSE README.md MANUAL.md BUILD-INFO.txt; do
|
||||
for required in sized sized.1 sized.bash _sized sized.fish LICENSE README.md MANUAL.md BUILD-INFO.txt LICENCES.txt DEPENDENCIES.json CORE-SNAPSHOT.json docs/UPGRADING-2.md docs/RELEASE-LICENSING.md; do
|
||||
test -s "$check_root/extracted/$required"
|
||||
done
|
||||
test -x "$check_root/extracted/sized"
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
[[ $# == 2 ]] || { echo 'Usage: scripts/notarize-macos.sh PACKAGE_DIRECTORY NEW_DMG_PATH' >&2; exit 2; }
|
||||
: "${SIZED_SIGN_IDENTITY:?Set a Developer ID Application identity.}"
|
||||
package=$1
|
||||
dmg=$2
|
||||
[[ ! -e $dmg && ! -L $dmg ]] || { echo 'Refusing existing DMG.' >&2; exit 1; }
|
||||
codesign --force --sign "$SIZED_SIGN_IDENTITY" --identifier com.gamertan.sized --options runtime --timestamp "$package/sized"
|
||||
codesign --verify --strict --verbose=2 "$package/sized"
|
||||
printf '\nMac distribution: Developer ID signed; see the notarized, stapled DMG.\n' >> "$package/BUILD-INFO.txt"
|
||||
hdiutil create -quiet -volname 'Sized 2.0.0' -srcfolder "$package" -format UDZO "$dmg"
|
||||
codesign --sign "$SIZED_SIGN_IDENTITY" --timestamp "$dmg"
|
||||
xcrun notarytool submit "$dmg" --keychain-profile "${SIZED_NOTARY_PROFILE:-sizequeen-notary}" --wait --output-format json > "$dmg.notarization.json"
|
||||
test "$(plutil -extract status raw "$dmg.notarization.json")" = Accepted
|
||||
xcrun stapler staple "$dmg"
|
||||
xcrun stapler validate "$dmg"
|
||||
spctl --assess --type open --context context:primary-signature --verbose=2 "$dmg"
|
||||
echo 'Signed, notarized and stapled disk image verified.'
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Preserve complete notices for the actual locked runtime/build crate graph."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
REVIEWED = {'GPL-3.0-only', 'MIT', 'MIT OR Apache-2.0', 'Apache-2.0 OR MIT',
|
||||
'MIT/Apache-2.0', 'Unlicense OR MIT', 'Unlicense/MIT', 'MPL-2.0',
|
||||
'Apache-2.0', 'Apache-2.0 OR BSL-1.0',
|
||||
'Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT',
|
||||
'BSD-2-Clause OR Apache-2.0 OR MIT',
|
||||
'Zlib OR Apache-2.0 OR MIT', 'MIT OR Apache-2.0 OR Zlib',
|
||||
'(MIT OR Apache-2.0) AND Unicode-3.0'}
|
||||
NOTICE_NAME = re.compile(r'^(licen[cs]e|copying|notice|unlicense|copyright)([-.]|$)', re.I)
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('destination', type=Path)
|
||||
p.add_argument('--revision', required=True)
|
||||
a = p.parse_args()
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
host = next(x[6:] for x in subprocess.check_output(['rustc', '-vV'], text=True).splitlines() if x.startswith('host: '))
|
||||
metadata = json.loads(subprocess.check_output(['cargo', 'metadata', '--locked', '--format-version', '1', '--filter-platform', host], cwd=root, text=True))
|
||||
# Cargo metadata includes dev-unified/optional edges; use Cargo's actual normal
|
||||
# and build tree to select the shipped graph instead of guessing feature edges.
|
||||
tree = subprocess.check_output(['cargo', 'tree', '--locked', '-p', 'sized', '--target', host, '--edges', 'normal,build', '--prefix', 'none', '--format', '{p}'], cwd=root, text=True)
|
||||
selected = {tuple(re.match(r'^(\S+) v(\S+)', line).groups()) for line in tree.splitlines()}
|
||||
packages = sorted([x for x in metadata['packages'] if (x['name'], x['version']) in selected], key=lambda x: (x['name'], x['version']))
|
||||
assert len(packages) == len(selected), 'Ambiguous or missing package identity'
|
||||
texts, inventory = {}, []
|
||||
for package in packages:
|
||||
if package['license'] not in REVIEWED:
|
||||
raise ValueError(f"Unreviewed licence: {package['name']} {package['license']}")
|
||||
directory = Path(package['manifest_path']).parent
|
||||
files = sorted(f for f in directory.iterdir() if f.is_file() and NOTICE_NAME.match(f.name))
|
||||
if not files:
|
||||
raise ValueError(f"Missing licence text: {package['name']}")
|
||||
notices = []
|
||||
for f in files:
|
||||
data = f.read_bytes(); text = data.decode('utf-8'); assert text.strip()
|
||||
digest = hashlib.sha256(data).hexdigest()
|
||||
texts.setdefault(digest, {'labels': [], 'text': text})['labels'].append(f"{package['name']} {package['version']} / {f.name}")
|
||||
notices.append({'file': f.name, 'sha256': digest})
|
||||
inventory.append({'name': package['name'], 'version': package['version'], 'license': package['license'], 'notices': notices})
|
||||
header = ['Sized - Licences and credits', '', f'Source revision: {a.revision}',
|
||||
f'Target: {host}', '', 'Sized and its core are GPL-3.0-only, without warranty.',
|
||||
'Matching source, including the pinned core and dependency sources, is available at:',
|
||||
'https://gamertan.com/projects/sized/ and the matching Gitea release.',
|
||||
'The colored 2.2.0 source remains under MPL-2.0 and is additionally distributed',
|
||||
'under GPL-3.0-only as part of this Larger Work under MPL section 3.3.',
|
||||
'All original notices are preserved. See docs/RELEASE-LICENSING.md in the source.', '',
|
||||
'Runtime and build dependencies (development-only dependencies are excluded):']
|
||||
header += [f" {x['name']} {x['version']} - {x['license']}" for x in inventory]
|
||||
for x in texts.values():
|
||||
header += ['', '='*72, '\n'.join(x['labels']), '='*72, x['text']]
|
||||
a.destination.mkdir(parents=True, exist_ok=True)
|
||||
(a.destination/'LICENCES.txt').write_text('\n'.join(header)+'\n')
|
||||
(a.destination/'DEPENDENCIES.json').write_text(json.dumps({'revision': a.revision, 'target': host, 'packages': inventory}, indent=2)+'\n')
|
||||
print(f'Packaged complete notices for {len(inventory)} runtime/build crates ({host}).')
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
repo_root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
cd "$repo_root"
|
||||
[[ $# == 1 && $1 == /* ]] || { echo 'Usage: scripts/package-source.sh ABSOLUTE_NEW_DIRECTORY' >&2; exit 2; }
|
||||
destination=$1
|
||||
[[ ! -e $destination && ! -L $destination ]] || { echo 'Refusing existing source output.' >&2; exit 1; }
|
||||
git diff --quiet HEAD -- || { echo 'Commit tracked changes before packaging.' >&2; exit 1; }
|
||||
revision=$(git rev-parse HEAD)
|
||||
mkdir -p "$destination"
|
||||
source_dir="$destination/sized-source"
|
||||
mkdir "$source_dir"
|
||||
git archive "$revision" | tar -x -C "$source_dir"
|
||||
mkdir -p "$source_dir/.cargo"
|
||||
cargo vendor --locked --versioned-dirs --manifest-path "$source_dir/Cargo.toml" "$source_dir/vendor" > "$destination/vendor-config"
|
||||
sed 's|directory = ".*"|directory = "vendor"|' "$destination/vendor-config" > "$source_dir/.cargo/config.toml"
|
||||
printf '%s\n' "$revision" > "$source_dir/SOURCE-REVISION.txt"
|
||||
cat > "$source_dir/BUILD-OFFLINE.txt" <<BUILD
|
||||
Sized 2.0.0 source checkpoint: $revision
|
||||
Requires Rust 1.88 or newer and the target platform's C linker/toolchain.
|
||||
From this directory: cargo build --locked --offline --release
|
||||
Test: cargo test --locked --offline --workspace (run as an ordinary user)
|
||||
Verify included core: python3 scripts/check-core.py
|
||||
Make an unsigned host archive: SIZED_SOURCE_REVISION=$revision scripts/release.sh
|
||||
Developer ID signing/notarization requires your own identity and is separate.
|
||||
BUILD
|
||||
(cd "$source_dir" && CARGO_HOME="$destination/empty-cargo-home" CARGO_TARGET_DIR="$destination/check-target" cargo check --locked --offline --workspace --all-targets)
|
||||
(cd "$source_dir" && python3 scripts/check-core.py)
|
||||
tar -czf "$destination/sized-v2.0.0-source.tar.gz" -C "$destination" sized-source
|
||||
printf '%s\n' "$revision" > "$destination/SOURCE-REVISION.txt"
|
||||
echo "Verified offline source: $destination/sized-v2.0.0-source.tar.gz"
|
||||
+5
-2
@@ -21,6 +21,7 @@ done
|
||||
|
||||
target_dir=${CARGO_TARGET_DIR:-"$repo_root/target"}
|
||||
[[ $target_dir == /* ]] || target_dir="$repo_root/$target_dir"
|
||||
python3 scripts/check-core.py
|
||||
cargo build --locked --release --target "$target" --target-dir "$target_dir"
|
||||
binary="$target_dir/$target/release/sized"
|
||||
mkdir -p "$destination"
|
||||
@@ -29,11 +30,13 @@ install -m 755 "$binary" "$destination/sized"
|
||||
"$binary" --completions bash > "$destination/sized.bash"
|
||||
"$binary" --completions zsh > "$destination/_sized"
|
||||
"$binary" --completions fish > "$destination/sized.fish"
|
||||
cp LICENSE README.md MANUAL.md "$destination/"
|
||||
cp LICENSE README.md MANUAL.md CORE-SNAPSHOT.json "$destination/"
|
||||
cp -R docs "$destination/"
|
||||
python3 scripts/package-notices.py "$destination" --revision "$revision"
|
||||
{
|
||||
printf 'Version: %s\nTarget: %s\nSource revision: %s\n' "$version" "$target" "$revision"
|
||||
printf 'Source worktree: '
|
||||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
if [[ $(git rev-parse --show-toplevel 2>/dev/null || true) == "$repo_root" ]]; then
|
||||
if git diff --quiet HEAD --; then printf 'clean tracked files\n'; else printf 'modified tracked files\n'; fi
|
||||
else
|
||||
printf 'exported source; verify against supplied revision\n'
|
||||
|
||||
Reference in New Issue
Block a user