feat(ci): add release manifest verification
This commit is contained in:
@@ -185,6 +185,25 @@ jobs:
|
|||||||
test -s "${ARTIFACT}.sha256" || { echo "ERROR: checksum file missing"; exit 1; }
|
test -s "${ARTIFACT}.sha256" || { echo "ERROR: checksum file missing"; exit 1; }
|
||||||
echo "✓ Checksum downloaded"
|
echo "✓ Checksum downloaded"
|
||||||
|
|
||||||
|
- name: Download Release Manifest
|
||||||
|
run: |
|
||||||
|
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
|
||||||
|
TOKEN="${{ secrets.GITEA_TOKEN }}"
|
||||||
|
RELEASE_TAG="${{ steps.fetch.outputs.tag }}"
|
||||||
|
MANIFEST_URL="https://gitea.taxbaik.com/api/v1/repos/${{ env.REPO }}/releases/tags/${RELEASE_TAG}"
|
||||||
|
|
||||||
|
RELEASE=$(curl -sf --connect-timeout 10 --max-time 30 -H "Authorization: token $TOKEN" "$MANIFEST_URL")
|
||||||
|
MANIFEST_DOWNLOAD_URL=$(echo "$RELEASE" | jq -r '.assets[] | select(.name == "'"${ARTIFACT}"'.manifest.json") | .browser_download_url')
|
||||||
|
|
||||||
|
if [ -z "$MANIFEST_DOWNLOAD_URL" ] || [ "$MANIFEST_DOWNLOAD_URL" = "null" ]; then
|
||||||
|
echo "ERROR: No manifest asset found for release $RELEASE_TAG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -sfL --connect-timeout 10 --max-time 120 -H "Authorization: token $TOKEN" -o "${ARTIFACT}.manifest.json" "$MANIFEST_DOWNLOAD_URL"
|
||||||
|
test -s "${ARTIFACT}.manifest.json" || { echo "ERROR: manifest file missing"; exit 1; }
|
||||||
|
echo "✓ Manifest downloaded"
|
||||||
|
|
||||||
- name: Validate Release Checksum
|
- name: Validate Release Checksum
|
||||||
run: |
|
run: |
|
||||||
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
|
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
|
||||||
@@ -198,6 +217,38 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "✓ Artifact checksum verified"
|
echo "✓ Artifact checksum verified"
|
||||||
|
|
||||||
|
- name: Validate Release Manifest
|
||||||
|
run: |
|
||||||
|
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
|
||||||
|
python3 - <<'PY'
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
|
||||||
|
artifact = pathlib.Path("${ARTIFACT}")
|
||||||
|
manifest = json.loads(pathlib.Path("${ARTIFACT}.manifest.json").read_text(encoding="utf-8"))
|
||||||
|
expected = {
|
||||||
|
"artifact": artifact.name,
|
||||||
|
"version": "${{ steps.fetch.outputs.tag }}",
|
||||||
|
"commit": "${{ steps.fetch.outputs.commit }}",
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in expected.items():
|
||||||
|
if manifest.get(key) != value:
|
||||||
|
print(f"ERROR: manifest {key} mismatch: {manifest.get(key)!r} != {value!r}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
actual_sha = hashlib.sha256(artifact.read_bytes()).hexdigest()
|
||||||
|
if manifest.get("sha256") != actual_sha:
|
||||||
|
print("ERROR: manifest sha256 mismatch")
|
||||||
|
print(f"Expected: {manifest.get('sha256')}")
|
||||||
|
print(f"Actual: {actual_sha}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print("✓ Manifest verified")
|
||||||
|
PY
|
||||||
|
|
||||||
- name: Setup SSH
|
- name: Setup SSH
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
|
|||||||
@@ -162,6 +162,30 @@ jobs:
|
|||||||
echo "✓ Checksum created: ${ARTIFACT}.sha256"
|
echo "✓ Checksum created: ${ARTIFACT}.sha256"
|
||||||
cat "${ARTIFACT}.sha256"
|
cat "${ARTIFACT}.sha256"
|
||||||
|
|
||||||
|
- name: Generate Release Manifest
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.metadata.outputs.version }}"
|
||||||
|
COMMIT="${{ steps.metadata.outputs.commit }}"
|
||||||
|
ARTIFACT="quantengine_${VERSION}.tar.gz"
|
||||||
|
CHECKSUM=$(cat "${ARTIFACT}.sha256")
|
||||||
|
python3 - <<PY
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"version": "${VERSION}",
|
||||||
|
"commit": "${COMMIT}",
|
||||||
|
"artifact": "${ARTIFACT}",
|
||||||
|
"sha256": "${CHECKSUM}",
|
||||||
|
}
|
||||||
|
pathlib.Path("${ARTIFACT}.manifest.json").write_text(
|
||||||
|
json.dumps(payload, ensure_ascii=False, indent=2),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
PY
|
||||||
|
echo "✓ Manifest created: ${ARTIFACT}.manifest.json"
|
||||||
|
cat "${ARTIFACT}.manifest.json"
|
||||||
|
|
||||||
- name: Create Git Tag
|
- name: Create Git Tag
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ steps.metadata.outputs.version }}"
|
VERSION="${{ steps.metadata.outputs.version }}"
|
||||||
@@ -225,6 +249,16 @@ jobs:
|
|||||||
|
|
||||||
echo "✓ Checksum attached: ${ARTIFACT}.sha256"
|
echo "✓ Checksum attached: ${ARTIFACT}.sha256"
|
||||||
|
|
||||||
|
echo "Uploading manifest..."
|
||||||
|
curl -sf -X POST \
|
||||||
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
|
-H "Content-Type: multipart/form-data" \
|
||||||
|
-F "attachment=@${ARTIFACT}.manifest.json" \
|
||||||
|
"${API}/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${ARTIFACT}.manifest.json" \
|
||||||
|
-o /dev/null
|
||||||
|
|
||||||
|
echo "✓ Manifest attached: ${ARTIFACT}.manifest.json"
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
name: Release Notification
|
name: Release Notification
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
Reference in New Issue
Block a user