feat(release): add Alibaba Cloud OSS distribution (#166)

This commit is contained in:
Laodouuu
2026-08-03 21:04:24 +08:00
committed by GitHub
parent 24cea8c511
commit 2e8389f438
13 changed files with 1199 additions and 57 deletions
+40
View File
@@ -0,0 +1,40 @@
#!/bin/sh
# Install a checksum-pinned ossutil 2 binary into a caller-provided directory.
# Usage: install-ossutil.sh <bin-dir>
set -eu
BIN_DIR="${1:?usage: install-ossutil.sh <bin-dir>}"
VERSION="2.3.0"
ARCHIVE="ossutil-$VERSION-linux-amd64.zip"
ARCHIVE_SHA256="3ae4d9fc85a7a6e9f5654d1599766f1a3a42a3692870887b5ae9338d582ef65a"
DOWNLOAD_URL="https://gosspublic.alicdn.com/ossutil/v2/$VERSION/$ARCHIVE"
command -v curl >/dev/null 2>&1 || {
echo "error: curl is required" >&2
exit 1
}
command -v sha256sum >/dev/null 2>&1 || {
echo "error: sha256sum is required" >&2
exit 1
}
command -v unzip >/dev/null 2>&1 || {
echo "error: unzip is required" >&2
exit 1
}
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
curl --proto '=https' --tlsv1.2 -fsSL "$DOWNLOAD_URL" -o "$WORK_DIR/$ARCHIVE"
printf '%s %s\n' "$ARCHIVE_SHA256" "$WORK_DIR/$ARCHIVE" | sha256sum -c -
unzip -q "$WORK_DIR/$ARCHIVE" -d "$WORK_DIR/extracted"
OSSUTIL_SOURCE="$(find "$WORK_DIR/extracted" -type f -name ossutil -print -quit)"
[ -n "$OSSUTIL_SOURCE" ] || {
echo "error: ossutil binary not found in $ARCHIVE" >&2
exit 1
}
mkdir -p "$BIN_DIR"
install -m 0755 "$OSSUTIL_SOURCE" "$BIN_DIR/ossutil"
"$BIN_DIR/ossutil" version
+220
View File
@@ -0,0 +1,220 @@
#!/bin/sh
# Mirror the exact assets downloaded from a GitHub Release into Alibaba Cloud OSS.
#
# Usage: publish-release-to-oss.sh <release-dir> <tag> [update-latest]
# update-latest: true only when <tag> is GitHub's current latest Release.
#
# Required environment:
# OSS_BUCKET, OSS_REGION, OSS_ENDPOINT, OSS_PUBLIC_BASE_URL and temporary
# OSS_* credentials.
set -eu
RELEASE_DIR="${1:?usage: publish-release-to-oss.sh <release-dir> <tag> [update-latest]}"
TAG="${2:?usage: publish-release-to-oss.sh <release-dir> <tag> [update-latest]}"
UPDATE_LATEST="${3:-false}"
OSSUTIL_BIN="${OSSUTIL_BIN:-ossutil}"
require_env() {
eval "value=\${$1:-}"
[ -n "$value" ] || {
echo "error: required environment variable $1 is empty" >&2
exit 1
}
}
for name in OSS_BUCKET OSS_REGION OSS_ENDPOINT OSS_PUBLIC_BASE_URL; do
require_env "$name"
done
[ -d "$RELEASE_DIR" ] || {
echo "error: release directory not found: $RELEASE_DIR" >&2
exit 1
}
case "$TAG" in
v[0-9]*) VERSION="${TAG#v}" ;;
*)
echo "error: release tag must start with v followed by a digit: $TAG" >&2
exit 1
;;
esac
case "$TAG" in
*[!A-Za-z0-9._+-]*|*..*)
echo "error: release tag is not safe for an OSS object prefix: $TAG" >&2
exit 1
;;
esac
case "$UPDATE_LATEST" in
true|false) ;;
*)
echo "error: update-latest must be true or false" >&2
exit 1
;;
esac
command -v "$OSSUTIL_BIN" >/dev/null 2>&1 || {
echo "error: ossutil not found: $OSSUTIL_BIN" >&2
exit 1
}
command -v sha256sum >/dev/null 2>&1 || {
echo "error: sha256sum is required" >&2
exit 1
}
command -v jq >/dev/null 2>&1 || {
echo "error: jq is required" >&2
exit 1
}
BUNDLES="
penguin-linux-x64.tar.gz
penguin-linux-arm64.tar.gz
penguin-darwin-x64.tar.gz
penguin-darwin-arm64.tar.gz
penguin-universal.tar.gz
penguin-win32-x64.zip
"
FILES="$BUNDLES
penguin-linux-x64.tar.gz.sha256
penguin-linux-arm64.tar.gz.sha256
penguin-darwin-x64.tar.gz.sha256
penguin-darwin-arm64.tar.gz.sha256
penguin-universal.tar.gz.sha256
penguin-win32-x64.zip.sha256
SHA256SUMS
install.sh
install.ps1
"
for file in $FILES; do
[ -f "$RELEASE_DIR/$file" ] || {
echo "error: missing GitHub Release asset: $file" >&2
exit 1
}
done
for bundle in $BUNDLES; do
(cd "$RELEASE_DIR" && sha256sum -c "$bundle.sha256")
done
(cd "$RELEASE_DIR" && sha256sum -c SHA256SUMS)
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
oss_cp() {
if [ -n "$3" ]; then
"$OSSUTIL_BIN" cp "$1" "$2" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" \
--force \
--no-progress \
--cache-control "$3"
else
"$OSSUTIL_BIN" cp "$1" "$2" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" \
--force \
--no-progress
fi
}
oss_put_if_absent() {
local_file="$1"
object_key="$2"
cache_control="$3"
"$OSSUTIL_BIN" api put-object \
--bucket "$OSS_BUCKET" \
--key "$object_key" \
--body "file://$local_file" \
--forbid-overwrite \
--cache-control "$cache_control" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION"
}
file_sha256() {
sha256sum "$1" | awk '{print $1}'
}
verify_remote_file() {
local_file="$1"
remote_uri="$2"
remote_file="$WORK_DIR/remote-$(basename "$local_file")"
rm -f "$remote_file"
oss_cp "$remote_uri" "$remote_file" ""
local_hash="$(file_sha256 "$local_file")"
remote_hash="$(file_sha256 "$remote_file")"
[ "$local_hash" = "$remote_hash" ] || {
echo "error: OSS object differs from the GitHub Release asset: $remote_uri" >&2
exit 1
}
}
upload_immutable_file() {
local_file="$1"
object_key="$2"
remote_uri="oss://$OSS_BUCKET/$object_key"
existing_file="$WORK_DIR/existing-$(basename "$local_file")"
rm -f "$existing_file"
# An exact-key download avoids needing ListObjects. Existing identical bytes make retries
# idempotent; different bytes fail before any upload is attempted.
if oss_cp "$remote_uri" "$existing_file" "" >/dev/null 2>&1; then
if [ "$(file_sha256 "$local_file")" = "$(file_sha256 "$existing_file")" ]; then
echo "Already mirrored: $remote_uri"
return
fi
echo "error: immutable OSS object already exists with different content: $remote_uri" >&2
exit 1
fi
echo "Uploading: $remote_uri"
if ! oss_put_if_absent "$local_file" "$object_key" "public,max-age=31536000,immutable"; then
# A concurrent retry may have won the create race. It is safe only if the resulting bytes match.
echo "Upload did not create $remote_uri; checking whether an identical object now exists."
fi
verify_remote_file "$local_file" "$remote_uri"
}
RELEASE_PREFIX="releases/$TAG"
for file in $FILES; do
upload_immutable_file "$RELEASE_DIR/$file" "$RELEASE_PREFIX/$file"
done
if [ "$UPDATE_LATEST" = "true" ]; then
# Re-check at the last possible moment. Another Release can finish while this job is
# transferring large assets; an older retry must never roll latest.json backwards.
require_env GH_TOKEN
require_env GITHUB_REPOSITORY
command -v gh >/dev/null 2>&1 || {
echo "error: gh is required when updating latest.json" >&2
exit 1
}
CURRENT_LATEST_TAG="$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName --jq .tagName)"
if [ "$TAG" != "$CURRENT_LATEST_TAG" ]; then
echo "Skipping latest.json because GitHub's latest Release changed to $CURRENT_LATEST_TAG."
UPDATE_LATEST=false
fi
fi
if [ "$UPDATE_LATEST" = "true" ]; then
PUBLIC_BASE="${OSS_PUBLIC_BASE_URL%/}/$RELEASE_PREFIX"
jq -n \
--arg tag "$TAG" \
--arg version "$VERSION" \
--arg releaseBaseUrl "$PUBLIC_BASE" \
'{
schemaVersion: 1,
tag: $tag,
version: $version,
releaseBaseUrl: $releaseBaseUrl
}' > "$WORK_DIR/latest.json"
LATEST_URI="oss://$OSS_BUCKET/latest.json"
echo "Updating latest release pointer: $LATEST_URI"
oss_cp "$WORK_DIR/latest.json" "$LATEST_URI" "no-cache"
verify_remote_file "$WORK_DIR/latest.json" "$LATEST_URI"
else
echo "Skipping latest.json because update-latest is false."
fi
echo "OSS mirror verified for $TAG."
+154 -3
View File
@@ -11,12 +11,19 @@ $Installer = Join-Path $RepoRoot "install.ps1"
$WorkDir = Join-Path ([IO.Path]::GetTempPath()) "penguin-installer-tests-$PID"
$OriginalPath = $env:Path
$OriginalOs = $env:OS
$OriginalDownloadBaseUrl = $env:PENGUIN_DOWNLOAD_BASE_URL
$OriginalDownloadFallbackBaseUrl = $env:PENGUIN_DOWNLOAD_FALLBACK_BASE_URL
$OriginalDownloadSource = $env:PENGUIN_DOWNLOAD_SOURCE
$OriginalArchive = $env:PENGUIN_ARCHIVE
$OriginalInstallDir = $env:PENGUIN_INSTALL_DIR
$OriginalVersion = $env:PENGUIN_VERSION
$Fixture = @{
Requests = [Collections.Generic.List[string]]::new()
Mode = "canonical"
GoodBundle = $null
BadInnerBundle = $null
LegacyArchive = $null
Installer = $Installer
}
$global:PenguinInstallerFixture = $Fixture
@@ -53,13 +60,39 @@ function global:Invoke-WebRequest {
param(
[Parameter(Mandatory = $true)][string]$Uri,
[Parameter(Mandatory = $true)][string]$OutFile,
[switch]$UseBasicParsing
[switch]$UseBasicParsing,
[int]$TimeoutSec = 0
)
$f = $global:PenguinInstallerFixture
$f.Requests.Add($Uri)
if ($f.Mode -eq "404") { throw "fixture 404: $Uri" }
if ($f.Mode -eq "network") { throw "fixture network failure: $Uri" }
if ($f.Mode -eq "primary-network" -and $Uri -like "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/*") {
throw "fixture primary network failure"
}
if ($f.Mode -eq "forced-oss-payload" -and
$Uri -like "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/*/penguin-*") {
throw "fixture forced OSS payload failure"
}
if ($f.Mode -eq "forwarder-auto-github" -and $Uri -like "*/latest.json") {
throw "fixture OSS metadata failure"
}
switch -Wildcard ($Uri) {
"*/latest.json" {
if ($f.Mode -eq "forwarder-invalid-metadata") {
'{"schemaVersion":1,"tag":"../invalid","releaseBaseUrl":"https://example.invalid"}' |
Set-Content -LiteralPath $OutFile -Encoding ascii
} else {
@{
schemaVersion = 1
tag = "v0.0.0-test"
releaseBaseUrl = "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test"
} | ConvertTo-Json | Set-Content -LiteralPath $OutFile -Encoding ascii
}
}
"*/install.ps1" {
Copy-Item -LiteralPath $f.Installer -Destination $OutFile
}
"*/penguin-win32-x64.zip.sha256" {
switch ($f.Mode) {
"outer-sha-mismatch" {
@@ -94,17 +127,54 @@ function Invoke-OnlineCase(
$Arguments = @{ InstallDir = $InstallDir }
if ($Version) { $Arguments.Version = $Version }
$Succeeded = $true
try { & $Installer @Arguments *>&1 | Out-Null } catch { $Succeeded = $false }
$Output = @()
try { $Output = @(& $Installer @Arguments *>&1) } catch { $Succeeded = $false }
Assert-True ($Succeeded -eq $ShouldSucceed) "$Name returned an unexpected result"
Assert-True ($Fixture.Requests.Count -eq $ExpectedRequests) `
"$Name made $($Fixture.Requests.Count) requests, expected $ExpectedRequests"
[PSCustomObject]@{ InstallDir = $InstallDir; Requests = @($Fixture.Requests) }
[PSCustomObject]@{ InstallDir = $InstallDir; Requests = @($Fixture.Requests); Output = @($Output) }
}
function Invoke-ForwarderCase(
[string]$Name,
[string]$Mode,
[string]$Source,
[int]$ExpectedRequests,
[string]$Version = "",
[bool]$ShouldSucceed = $true
) {
$Fixture.Mode = $Mode
$Fixture.Requests.Clear()
$InstallDir = Join-Path $WorkDir "$Name-install"
if ($Version) {
Remove-Item Env:\PENGUIN_ARCHIVE -ErrorAction SilentlyContinue
$env:PENGUIN_VERSION = $Version
} else {
$env:PENGUIN_ARCHIVE = $Fixture.GoodBundle
Remove-Item Env:\PENGUIN_VERSION -ErrorAction SilentlyContinue
}
$env:PENGUIN_INSTALL_DIR = $InstallDir
$env:PENGUIN_DOWNLOAD_SOURCE = $Source
Remove-Item Env:\PENGUIN_DOWNLOAD_BASE_URL, Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL -ErrorAction SilentlyContinue
$Forwarder = Join-Path $RepoRoot "packages\landing\public\install.ps1"
$Output = @()
$Succeeded = $true
try { $Output = @(& $Forwarder *>&1) } catch { $Succeeded = $false }
Assert-True ($Succeeded -eq $ShouldSucceed) "$Name returned an unexpected result"
Assert-True ($Fixture.Requests.Count -eq $ExpectedRequests) `
"$Name made $($Fixture.Requests.Count) requests, expected $ExpectedRequests"
Assert-True (-not (($Output | Out-String) -match 'aliyuncs\.com')) `
"$Name exposed the OSS URL in normal output"
[PSCustomObject]@{ InstallDir = $InstallDir; Requests = @($Fixture.Requests); Output = @($Output) }
}
try {
New-Item -ItemType Directory -Path $WorkDir -Force | Out-Null
# Keep the fixture tests away from the runner's user registry Path.
$env:OS = "PenguinInstallerFixtureTest"
Remove-Item Env:\PENGUIN_DOWNLOAD_BASE_URL, Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL, `
Env:\PENGUIN_DOWNLOAD_SOURCE, Env:\PENGUIN_ARCHIVE, Env:\PENGUIN_INSTALL_DIR, `
Env:\PENGUIN_VERSION -ErrorAction SilentlyContinue
# --- Offline program archive: good install, then a failing upgrade must roll back. ---
$InstallDir = Join-Path $WorkDir "offline-installed"
@@ -171,6 +241,57 @@ try {
"canonical did not request the canonical bundle"
$Version = & (Join-Path $canonical.InstallDir "bin\penguin.cmd") --version
Assert-True ($Version -eq "fixture-old") "canonical bundle was not installed"
$env:PENGUIN_DOWNLOAD_BASE_URL = "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test"
$override = Invoke-OnlineCase "download-base-override" "canonical" "" $true 2
Assert-True ($override.Requests[0] -eq "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test/penguin-win32-x64.zip") `
"download base override did not request the configured asset directory"
Assert-True (($override.Output | Out-String) -match 'OSS mirror') `
"download base override did not identify the OSS mirror"
Assert-True (-not (($override.Output | Out-String) -match 'aliyuncs\.com')) `
"download base override exposed the OSS URL in normal output"
$env:PENGUIN_DOWNLOAD_FALLBACK_BASE_URL = "https://github.com/Prism-Shadow/penguin-harness/releases/download/v0.0.0-test"
$fallback = Invoke-OnlineCase "download-fallback" "primary-network" "" $true 3
Assert-True ($fallback.Requests[0] -like "https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/*") `
"download fallback did not try the primary source first"
Assert-True ($fallback.Requests[1] -like "https://github.com/*/penguin-win32-x64.zip") `
"download fallback did not use the same-version GitHub source"
Assert-True (-not (($fallback.Output | Out-String) -match 'aliyuncs\.com')) `
"download fallback exposed the OSS URL in normal output"
Remove-Item Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL
Remove-Item Env:\PENGUIN_DOWNLOAD_BASE_URL
$forwarderOss = Invoke-ForwarderCase "forwarder-oss" "forwarder-oss" "auto" 2
Assert-True ($forwarderOss.Requests[0] -like "*/latest.json") `
"OSS forwarder did not request release metadata first"
Assert-True ($forwarderOss.Requests[1] -like "*/releases/v0.0.0-test/install.ps1") `
"OSS forwarder did not request the versioned installer"
$forwarderGitHub = Invoke-ForwarderCase "forwarder-auto-github" "forwarder-auto-github" "auto" 2
Assert-True ($forwarderGitHub.Requests[1] -like "https://github.com/*/releases/latest/download/install.ps1") `
"forwarder did not fall back to the GitHub installer"
$invalidMetadata = Invoke-ForwarderCase "forwarder-invalid-metadata" "forwarder-invalid-metadata" "auto" 2
Assert-True ($invalidMetadata.Requests[1] -like "https://github.com/*/releases/latest/download/install.ps1") `
"invalid OSS metadata did not fall back to the GitHub installer"
$forcedGitHub = Invoke-ForwarderCase "forwarder-github" "canonical" "github" 1
Assert-True ($forcedGitHub.Requests[0] -like "https://github.com/*/releases/latest/download/install.ps1") `
"forced GitHub mode did not request the GitHub installer"
$forcedOss = Invoke-ForwarderCase "forwarder-forced-oss-no-fallback" `
"forced-oss-payload" "oss" 2 "v0.0.0-test" $false
Assert-True (-not (($forcedOss.Requests | Out-String) -match 'github\.com')) `
"forced OSS mode unexpectedly fell back to GitHub"
$pinnedForwarder = Invoke-ForwarderCase "forwarder-pinned" "canonical" "auto" 3 "v0.0.0-test"
Assert-True ($pinnedForwarder.Requests[0] -like "*/releases/v0.0.0-test/install.ps1") `
"pinned forwarder did not request the versioned installer"
Assert-True ($pinnedForwarder.Requests[1] -like "*/releases/v0.0.0-test/penguin-win32-x64.zip") `
"pinned installer did not keep the selected release version"
Remove-Item Env:\PENGUIN_ARCHIVE, Env:\PENGUIN_INSTALL_DIR, Env:\PENGUIN_DOWNLOAD_SOURCE, Env:\PENGUIN_VERSION -ErrorAction SilentlyContinue
Invoke-OnlineCase "outer-mismatch" "outer-sha-mismatch" "" $false 2 | Out-Null
Invoke-OnlineCase "inner-mismatch" "inner-sha-mismatch" "" $false 2 | Out-Null
Invoke-OnlineCase "latest-404" "404" "" $false 1 | Out-Null
@@ -183,6 +304,36 @@ try {
} finally {
$env:Path = $OriginalPath
$env:OS = $OriginalOs
if ($null -eq $OriginalDownloadBaseUrl) {
Remove-Item Env:\PENGUIN_DOWNLOAD_BASE_URL -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_DOWNLOAD_BASE_URL = $OriginalDownloadBaseUrl
}
if ($null -eq $OriginalDownloadFallbackBaseUrl) {
Remove-Item Env:\PENGUIN_DOWNLOAD_FALLBACK_BASE_URL -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_DOWNLOAD_FALLBACK_BASE_URL = $OriginalDownloadFallbackBaseUrl
}
if ($null -eq $OriginalDownloadSource) {
Remove-Item Env:\PENGUIN_DOWNLOAD_SOURCE -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_DOWNLOAD_SOURCE = $OriginalDownloadSource
}
if ($null -eq $OriginalArchive) {
Remove-Item Env:\PENGUIN_ARCHIVE -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_ARCHIVE = $OriginalArchive
}
if ($null -eq $OriginalInstallDir) {
Remove-Item Env:\PENGUIN_INSTALL_DIR -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_INSTALL_DIR = $OriginalInstallDir
}
if ($null -eq $OriginalVersion) {
Remove-Item Env:\PENGUIN_VERSION -ErrorAction SilentlyContinue
} else {
$env:PENGUIN_VERSION = $OriginalVersion
}
Remove-Item Function:\Invoke-WebRequest -ErrorAction SilentlyContinue
Remove-Variable PenguinInstallerFixture -Scope Global -ErrorAction SilentlyContinue
if (Test-Path -LiteralPath $WorkDir) { Remove-Item -LiteralPath $WorkDir -Recurse -Force }
+109 -2
View File
@@ -242,19 +242,36 @@ url=""
while [ $# -gt 0 ]; do
case "$1" in
-o) output="$2"; shift 2 ;;
--connect-timeout | --max-time) shift 2 ;;
-*) shift ;;
*) url="$1"; shift ;;
esac
done
printf '%s\n' "$url" >> "$REQUEST_LOG"
base="${url##*/}"
case "$MODE:$url" in
primary-network:https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/*) exit 7 ;;
forced-oss-payload:https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/*/penguin-*) exit 7 ;;
esac
case "$MODE:$base" in
forwarder-auto-github:latest.json) exit 7 ;;
forwarder-invalid-metadata:latest.json)
printf '%s\n' '{"schemaVersion":1,"tag":"../invalid","releaseBaseUrl":"https://example.invalid"}' > "$output"
;;
forwarder-oss:latest.json | forced-oss-payload:latest.json)
printf '%s\n' '{"schemaVersion":1,"tag":"v0.0.0-test","releaseBaseUrl":"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test"}' > "$output"
;;
forwarder-oss:install.sh | forced-oss-payload:install.sh | forwarder-auto-github:install.sh | forwarder-invalid-metadata:install.sh | canonical:install.sh) cp "$ROOT_DIR/install.sh" "$output" ;;
404:penguin-*) exit 22 ;;
network:penguin-*) exit 7 ;;
outer-sha-mismatch:penguin-*.sha256) printf '%064d %s\n' 0 "${base%.sha256}" > "$output" ;;
outer-sha-mismatch:penguin-*) cp "$ARTIFACT_DIR/$base" "$output" ;;
inner-sha-mismatch:penguin-*.sha256) cp "$BAD_BUNDLE.sha256" "$output" ;;
inner-sha-mismatch:penguin-*) cp "$BAD_BUNDLE" "$output" ;;
primary-network:penguin-*.sha256) cp "$ARTIFACT_DIR/$base" "$output" ;;
primary-network:penguin-*) cp "$ARTIFACT_DIR/$base" "$output" ;;
forced-oss-payload:penguin-*.sha256) cp "$ARTIFACT_DIR/$base" "$output" ;;
forced-oss-payload:penguin-*) cp "$ARTIFACT_DIR/$base" "$output" ;;
legacy:penguin-*.sha256) cp "$LEGACY_ARCHIVE.sha256" "$output" ;;
legacy:penguin-*) cp "$LEGACY_ARCHIVE" "$output" ;;
canonical:penguin-*.sha256) cp "$ARTIFACT_DIR/$base" "$output" ;;
@@ -263,7 +280,7 @@ case "$MODE:$base" in
esac
EOF
chmod +x "$STUB_BIN/curl"
export ARTIFACT_DIR BAD_BUNDLE LEGACY_ARCHIVE
export ARTIFACT_DIR BAD_BUNDLE LEGACY_ARCHIVE ROOT_DIR
run_online_case() {
name="$1"
@@ -271,13 +288,18 @@ run_online_case() {
version="$3"
expected="$4"
expected_requests="$5"
download_base_url="${6:-}"
download_fallback_base_url="${7:-}"
CASE_LOG="$WORK_DIR/$name.log"
CASE_OUTPUT="$WORK_DIR/$name.output"
CASE_INSTALL="$WORK_DIR/$name-install"
: > "$CASE_LOG"
set +e
REQUEST_LOG="$CASE_LOG" MODE="$mode" PATH="$STUB_BIN:$PATH" \
HOME="$WORK_DIR/$name-home" PENGUIN_INSTALL_DIR="$CASE_INSTALL" \
PENGUIN_VERSION="$version" sh "$ROOT_DIR/install.sh" >/dev/null 2>&1
PENGUIN_VERSION="$version" PENGUIN_DOWNLOAD_BASE_URL="$download_base_url" \
PENGUIN_DOWNLOAD_FALLBACK_BASE_URL="$download_fallback_base_url" \
sh "$ROOT_DIR/install.sh" >"$CASE_OUTPUT" 2>&1
status=$?
set -e
if [ "$expected" = "success" ]; then
@@ -294,6 +316,22 @@ run_online_case canonical canonical "" success 2
|| fail_test "canonical online install did not produce a working command"
grep -q "/releases/latest/download/$HOST_ASSET\$" "$WORK_DIR/canonical.log" \
|| fail_test "canonical did not request the canonical bundle"
run_online_case download-base-override canonical "" success 2 \
"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test" ""
grep -q "OSS mirror" "$WORK_DIR/download-base-override.output" \
|| fail_test "download base override did not identify the OSS mirror"
! grep -q "aliyuncs.com" "$WORK_DIR/download-base-override.output" \
|| fail_test "download base override exposed the OSS URL in normal output"
run_online_case download-fallback primary-network "" success 3 \
"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test" \
"https://github.com/Prism-Shadow/penguin-harness/releases/download/v0.0.0-test"
[ "$(sed -n '1p' "$WORK_DIR/download-fallback.log")" = \
"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test/$HOST_ASSET" ] \
|| fail_test "download fallback did not try the primary source first"
grep -q "github.com/.*/releases/download/v0.0.0-test/$HOST_ASSET\$" "$WORK_DIR/download-fallback.log" \
|| fail_test "download fallback did not use the same-version GitHub source"
! grep -q "aliyuncs.com" "$WORK_DIR/download-fallback.output" \
|| fail_test "download fallback exposed the OSS URL in normal output"
run_online_case outer-mismatch outer-sha-mismatch "" failure 2
run_online_case inner-mismatch inner-sha-mismatch "" failure 2
run_online_case latest-404 404 "" failure 1
@@ -302,4 +340,73 @@ run_online_case pinned-legacy legacy v0.1.4 success 2
grep -q "/releases/download/v0.1.4/$HOST_ASSET\$" "$WORK_DIR/pinned-legacy.log" \
|| fail_test "pinned legacy did not request the pinned asset"
# --- Stable penguin.ooo forwarder: prefer a validated immutable OSS release, but fall back to
# GitHub when the metadata probe fails. The real installer uses a local fixture here so the
# test isolates bootstrap routing from bundle download behavior above. ---
run_forwarder_case() {
name="$1"
mode="$2"
expected_requests="$3"
source="${4:-auto}"
version="${5:-}"
expected="${6:-success}"
CASE_LOG="$WORK_DIR/$name.log"
CASE_OUTPUT="$WORK_DIR/$name.output"
CASE_INSTALL="$WORK_DIR/$name-install"
: > "$CASE_LOG"
if [ -n "$version" ]; then
archive=""
else
archive="$ARTIFACT_DIR/$HOST_ASSET"
fi
set +e
REQUEST_LOG="$CASE_LOG" MODE="$mode" PATH="$STUB_BIN:$PATH" \
HOME="$WORK_DIR/$name-home" PENGUIN_INSTALL_DIR="$CASE_INSTALL" \
PENGUIN_ARCHIVE="$archive" PENGUIN_VERSION="$version" \
PENGUIN_DOWNLOAD_SOURCE="$source" PENGUIN_DOWNLOAD_BASE_URL="" \
PENGUIN_DOWNLOAD_FALLBACK_BASE_URL="" \
sh "$ROOT_DIR/packages/landing/public/install.sh" >"$CASE_OUTPUT" 2>&1
status=$?
set -e
if [ "$expected" = "success" ]; then
[ "$status" -eq 0 ] || fail_test "$name unexpectedly failed"
else
[ "$status" -ne 0 ] || fail_test "$name unexpectedly succeeded"
fi
[ "$(wc -l < "$CASE_LOG" | tr -d ' ')" -eq "$expected_requests" ] \
|| fail_test "$name made an unexpected number of requests"
! grep -q "aliyuncs.com" "$CASE_OUTPUT" \
|| fail_test "$name exposed the OSS URL in normal output"
}
run_forwarder_case forwarder-oss forwarder-oss 2
grep -q "/latest.json\$" "$WORK_DIR/forwarder-oss.log" \
|| fail_test "OSS forwarder did not request release metadata first"
grep -q "/releases/v0.0.0-test/install.sh\$" "$WORK_DIR/forwarder-oss.log" \
|| fail_test "OSS forwarder did not request the versioned installer"
run_forwarder_case forwarder-auto-github forwarder-auto-github 2
grep -q "github.com/.*/releases/latest/download/install.sh\$" "$WORK_DIR/forwarder-auto-github.log" \
|| fail_test "forwarder did not fall back to the GitHub installer"
run_forwarder_case forwarder-invalid-metadata forwarder-invalid-metadata 2
grep -q "github.com/.*/releases/latest/download/install.sh\$" "$WORK_DIR/forwarder-invalid-metadata.log" \
|| fail_test "invalid OSS metadata did not fall back to the GitHub installer"
run_forwarder_case forwarder-github canonical 1 github
grep -q "github.com/.*/releases/latest/download/install.sh\$" "$WORK_DIR/forwarder-github.log" \
|| fail_test "forced GitHub mode did not request the GitHub installer"
run_forwarder_case forwarder-forced-oss-no-fallback forced-oss-payload 2 oss v0.0.0-test failure
! grep -q "github.com" "$WORK_DIR/forwarder-forced-oss-no-fallback.log" \
|| fail_test "forced OSS mode unexpectedly fell back to GitHub"
run_forwarder_case forwarder-pinned canonical 3 auto v0.0.0-test
[ "$(sed -n '1p' "$WORK_DIR/forwarder-pinned.log")" = \
"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test/install.sh" ] \
|| fail_test "pinned forwarder did not request the versioned installer"
[ "$(sed -n '2p' "$WORK_DIR/forwarder-pinned.log")" = \
"https://penguin-harness-releases.oss-cn-beijing.aliyuncs.com/releases/v0.0.0-test/$HOST_ASSET" ] \
|| fail_test "pinned installer did not keep the selected release version"
echo "Installer bundle, offline, rollback and online tests passed."
+102
View File
@@ -0,0 +1,102 @@
#!/bin/sh
# Verify a GitHub Actions OIDC staging role can round-trip an object under staging/
# and cannot write either releases/ or the production latest.json pointer.
set -eu
OSSUTIL_BIN="${OSSUTIL_BIN:-ossutil}"
RUN_ID="${GITHUB_RUN_ID:-manual}"
RUN_ATTEMPT="${GITHUB_RUN_ATTEMPT:-1}"
PREFIX="${1:-staging/$RUN_ID-$RUN_ATTEMPT}"
require_env() {
eval "value=\${$1:-}"
[ -n "$value" ] || {
echo "error: required environment variable $1 is empty" >&2
exit 1
}
}
for name in OSS_BUCKET OSS_REGION OSS_ENDPOINT OSS_PUBLIC_BASE_URL; do
require_env "$name"
done
case "$PREFIX" in
staging/*) ;;
*)
echo "error: staging prefix must start with staging/: $PREFIX" >&2
exit 1
;;
esac
command -v "$OSSUTIL_BIN" >/dev/null 2>&1 || {
echo "error: ossutil not found: $OSSUTIL_BIN" >&2
exit 1
}
command -v curl >/dev/null 2>&1 || {
echo "error: curl is required" >&2
exit 1
}
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
PROBE="$WORK_DIR/oidc-probe.txt"
DOWNLOADED="$WORK_DIR/downloaded.txt"
printf 'repository=%s\nrun_id=%s\nrun_attempt=%s\ncommit=%s\n' \
"${GITHUB_REPOSITORY:-unknown}" "$RUN_ID" "$RUN_ATTEMPT" "${GITHUB_SHA:-unknown}" > "$PROBE"
oss_cp() {
"$OSSUTIL_BIN" cp "$1" "$2" \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" \
--force \
--no-progress
}
STAGING_URI="oss://$OSS_BUCKET/$PREFIX/oidc-probe.txt"
oss_cp "$PROBE" "$STAGING_URI"
oss_cp "$STAGING_URI" "$DOWNLOADED"
cmp "$PROBE" "$DOWNLOADED"
echo "Staging upload/download verified: $STAGING_URI"
DENIED_URI="oss://$OSS_BUCKET/releases/_staging-deny-probe/$RUN_ID-$RUN_ATTEMPT.txt"
if oss_cp "$PROBE" "$DENIED_URI" >"$WORK_DIR/denied.log" 2>&1; then
echo "error: staging role unexpectedly wrote to production: $DENIED_URI" >&2
echo "Remove that probe manually and fix the RAM policy before continuing." >&2
exit 1
fi
if ! grep -Eiq 'AccessDenied|Forbidden|(^|[^0-9])403([^0-9]|$)' "$WORK_DIR/denied.log"; then
echo "error: production probe failed, but not with a recognizable access-denied response" >&2
cat "$WORK_DIR/denied.log" >&2
exit 1
fi
echo "Production write correctly denied for the staging role."
# Probe the exact latest.json permission without risking an overwrite. The existing public
# object is used as the body and x-oss-forbid-overwrite makes the request non-destructive:
# AccessDenied is expected; FileAlreadyExists means the role was incorrectly authorized.
LATEST_COPY="$WORK_DIR/latest.json"
LATEST_URL="${OSS_PUBLIC_BASE_URL%/}/latest.json"
curl --proto '=https' --tlsv1.2 -fsSL "$LATEST_URL" -o "$LATEST_COPY"
[ -s "$LATEST_COPY" ] || {
echo "error: downloaded latest.json is empty: $LATEST_URL" >&2
exit 1
}
if "$OSSUTIL_BIN" api put-object \
--bucket "$OSS_BUCKET" \
--key latest.json \
--body "file://$LATEST_COPY" \
--forbid-overwrite \
--endpoint "$OSS_ENDPOINT" \
--region "$OSS_REGION" >"$WORK_DIR/latest-denied.log" 2>&1; then
echo "error: staging role unexpectedly wrote the production latest.json pointer" >&2
exit 1
fi
if grep -Eiq 'AccessDenied|Forbidden|(^|[^0-9])403([^0-9]|$)' "$WORK_DIR/latest-denied.log"; then
echo "Production latest.json write correctly denied for the staging role."
elif grep -Eiq 'FileAlreadyExists|(^|[^0-9])409([^0-9]|$)' "$WORK_DIR/latest-denied.log"; then
echo "error: staging role is authorized to write latest.json; overwrite was blocked by OSS" >&2
exit 1
else
echo "error: latest.json probe failed, but not with a recognizable access-denied response" >&2
cat "$WORK_DIR/latest-denied.log" >&2
exit 1
fi