Files
GenericAgent/.github/workflows/desktop-release-package.yml
T

118 lines
4.7 KiB
YAML

name: Assemble GA source deployment
# Windows publication still follows the existing release SOP.
# This workflow assembles source + a prebuilt component, never private source.
"on":
workflow_dispatch:
inputs:
platform:
description: Desktop component platform
required: true
type: choice
options: [windows, macos, linux]
component_url:
description: Public HTTPS URL of the exe, signed app ZIP, or AppImage
required: true
type: string
component_sha256:
description: Expected SHA256 from the Desktop component build
required: true
type: string
permissions:
contents: read
jobs:
assemble:
runs-on: ${{ inputs.platform == 'macos' && 'macos-14' || 'ubuntu-24.04' }}
timeout-minutes: 20
env:
PLATFORM: ${{ inputs.platform }}
COMPONENT_URL: ${{ inputs.component_url }}
COMPONENT_SHA256: ${{ inputs.component_sha256 }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
with:
persist-credentials: false
- name: Fetch fixed component and export GA source
shell: bash
run: |
set -euo pipefail
[[ "$COMPONENT_URL" == https://* ]]
[[ "$COMPONENT_SHA256" =~ ^[0-9a-fA-F]{64}$ ]]
mkdir -p staging/GenericAgent out
curl --fail --location --retry 3 --proto '=https' --proto-redir '=https' \
--output component.bin "$COMPONENT_URL"
python3 - <<'PY'
import hashlib, os
from pathlib import Path
actual = hashlib.sha256(Path('component.bin').read_bytes()).hexdigest()
assert actual == os.environ['COMPONENT_SHA256'].lower(), 'Component SHA256 mismatch'
PY
git archive HEAD | tar -x -C staging/GenericAgent
mkdir -p staging/GenericAgent/frontends
- name: Install component into source tree
shell: bash
run: |
set -euo pipefail
FRONTENDS=staging/GenericAgent/frontends
case "$PLATFORM" in
windows)
cp component.bin "$FRONTENDS/GenericAgent.exe"
;;
macos)
# Reject archive traversal; ditto preserves app modes, links and signature.
python3 - <<'PY'
import zipfile
from pathlib import PurePosixPath
with zipfile.ZipFile('component.bin') as archive:
for name in archive.namelist():
path = PurePosixPath(name)
assert not path.is_absolute() and '..' not in path.parts and '\\' not in name, name
assert path.parts and path.parts[0] in ('GenericAgent.app', '__MACOSX'), name
PY
ditto -x -k component.bin "$FRONTENDS"
test -d "$FRONTENDS/GenericAgent.app"
rm -rf "$FRONTENDS/__MACOSX"
codesign --verify --deep --strict "$FRONTENDS/GenericAgent.app"
;;
linux)
cp component.bin "$FRONTENDS/GenericAgent.AppImage"
chmod +x "$FRONTENDS/GenericAgent.AppImage"
;;
esac
python3 - <<'PY'
import json, os
from pathlib import Path
record = {'ga_commit': os.environ['GITHUB_SHA'], 'platform': os.environ['PLATFORM'],
'component_url': os.environ['COMPONENT_URL'], 'component_sha256': os.environ['COMPONENT_SHA256'].lower()}
Path('staging/GenericAgent/DESKTOP_COMPONENT.json').write_text(json.dumps(record, indent=2) + '\n')
PY
- name: Archive and verify deployment
shell: bash
run: |
set -euo pipefail
NAME="GenericAgent-Source-$PLATFORM"
if [[ "$PLATFORM" == macos ]]; then
ditto -c -k --sequesterRsrc --keepParent staging/GenericAgent "out/$NAME.zip"
ditto -x -k "out/$NAME.zip" "$RUNNER_TEMP/deployment-verify"
codesign --verify --deep --strict "$RUNNER_TEMP/deployment-verify/GenericAgent/frontends/GenericAgent.app"
elif [[ "$PLATFORM" == windows ]]; then
(cd staging && zip -qr "../out/$NAME.zip" GenericAgent)
else
tar -czf "out/$NAME.tar.gz" -C staging GenericAgent
fi
python3 - <<'PY'
import hashlib
from pathlib import Path
for path in list(Path('out').iterdir()):
digest = hashlib.sha256(path.read_bytes()).hexdigest()
path.with_name(path.name + '.sha256').write_text(digest + ' ' + path.name + '\n')
PY
- uses: actions/upload-artifact@v4
with:
name: ga-source-${{ inputs.platform }}
path: out/*
if-no-files-found: error
retention-days: 30