Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 144 additions & 2 deletions .github/workflows/_build-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ on:
description: 'AionCore managed resources bundle mode: full or no-acp'
type: string
default: full
desktop_bridge_payload_repository:
description: 'Repository containing the reviewed Desktop Bridge payload workflow run'
type: string
default: 'electricsheephq/evaos-desktop-bridge'
desktop_bridge_payload_run_id:
description: 'Exact successful Desktop Bridge workflow run id containing the reviewed payload artifact'
type: string
default: ''
desktop_bridge_payload_artifact_name:
description: 'Exact Desktop Bridge Actions artifact name'
type: string
default: 'evaos-desktop-bridge-macos-arm64'
desktop_bridge_payload_sha256:
description: 'Approved sha256-tree-v1 payload digest'
type: string
default: ''
desktop_bridge_manifest_sha256:
description: 'Approved raw payload-manifest.json SHA-256 digest'
type: string
default: ''

env:
BUN_INSTALL_REGISTRY: 'https://registry.npmjs.org/'
Expand Down Expand Up @@ -625,6 +645,117 @@ jobs:
rm -f /tmp/*.dmg 2>/dev/null || true
echo "Cleanup complete"

- name: Preflight pinned Desktop Bridge payload inputs (macOS only)
if: startsWith(matrix.platform, 'macos')
shell: bash
env:
REPOSITORY: ${{ inputs.desktop_bridge_payload_repository }}
RUN_ID: ${{ inputs.desktop_bridge_payload_run_id }}
ARTIFACT_NAME: ${{ inputs.desktop_bridge_payload_artifact_name }}
PAYLOAD_SHA256: ${{ inputs.desktop_bridge_payload_sha256 }}
MANIFEST_SHA256: ${{ inputs.desktop_bridge_manifest_sha256 }}
run: |
set -euo pipefail
if [ -z "$REPOSITORY" ] || [ -z "$RUN_ID" ] || [ -z "$ARTIFACT_NAME" ]; then
echo "::error::macOS release builds require an exact Desktop Bridge repository, workflow run id, and artifact name."
exit 1
fi
if [[ ! "$PAYLOAD_SHA256" =~ ^[0-9a-fA-F]{64}$ ]] || [[ ! "$MANIFEST_SHA256" =~ ^[0-9a-fA-F]{64}$ ]]; then
echo "::error::macOS release builds require valid payload and manifest SHA-256 pins."
exit 1
fi
if [ "${{ matrix.arch }}" != "arm64" ]; then
echo "::error::The current self-contained Desktop Bridge producer contract supports macOS arm64 only."
exit 1
fi

- name: Download pinned Desktop Bridge payload (macOS only)
if: startsWith(matrix.platform, 'macos')
uses: actions/download-artifact@v7
with:
repository: ${{ inputs.desktop_bridge_payload_repository }}
run-id: ${{ inputs.desktop_bridge_payload_run_id }}
name: ${{ inputs.desktop_bridge_payload_artifact_name }}
path: ${{ runner.temp }}/evaos-desktop-bridge-artifact
github-token: ${{ secrets.EVAOS_DESKTOP_BRIDGE_ACTIONS_TOKEN || secrets.GH_TOKEN || secrets.GITHUB_TOKEN || github.token }}

- name: Verify pinned Desktop Bridge payload identity (macOS only)
if: startsWith(matrix.platform, 'macos')
shell: bash
env:
PAYLOAD_SHA256: ${{ inputs.desktop_bridge_payload_sha256 }}
MANIFEST_SHA256: ${{ inputs.desktop_bridge_manifest_sha256 }}
run: |
set -euo pipefail
ARTIFACT_DIR="${RUNNER_TEMP}/evaos-desktop-bridge-artifact"
ARCHIVE_PATH="$ARTIFACT_DIR/evaos-desktop-bridge-macos-arm64.tar.gz"
PAYLOAD_DIR="${RUNNER_TEMP}/evaos-desktop-bridge-payload"
MANIFEST_PATH="$PAYLOAD_DIR/payload-manifest.json"
if [ ! -f "$ARCHIVE_PATH" ] || [ -L "$ARCHIVE_PATH" ]; then
echo "::error::Desktop Bridge artifact must contain the fixed payload tar archive."
exit 1
fi
rm -rf "$PAYLOAD_DIR"
mkdir -p "$PAYLOAD_DIR"
python3 - "$ARCHIVE_PATH" "$PAYLOAD_DIR" <<'PY'
import pathlib
import sys
import tarfile

archive_path = pathlib.Path(sys.argv[1])
payload_dir = pathlib.Path(sys.argv[2])
max_payload_bytes = 1024 * 1024 * 1024
max_file_bytes = 512 * 1024 * 1024
max_members = 100_000
max_path_bytes = 1024
seen = set()
total_bytes = 0
with tarfile.open(archive_path, mode="r:gz") as archive:
members = []
for member in archive:
if len(members) >= max_members:
raise SystemExit("desktop_bridge_archive_exceeds_member_limit")
members.append(member)
for member in members:
relative = pathlib.PurePosixPath(member.name)
if relative.is_absolute() or ".." in relative.parts:
raise SystemExit("unsafe_path_in_desktop_bridge_archive")
if any(ord(char) < 32 or ord(char) == 127 for char in member.name):
raise SystemExit("control_character_in_desktop_bridge_archive_path")
if len(member.name.encode("utf-8")) > max_path_bytes:
raise SystemExit("desktop_bridge_archive_path_exceeds_limit")
normalized = relative.as_posix().removeprefix("./")
if not normalized or normalized in seen:
raise SystemExit("duplicate_or_empty_desktop_bridge_archive_path")
seen.add(normalized)
if not (member.isfile() or member.isdir()):
raise SystemExit("link_or_special_file_in_desktop_bridge_archive")
if member.isfile():
if member.size > max_file_bytes:
raise SystemExit("desktop_bridge_archive_file_exceeds_size_limit")
total_bytes += member.size
if total_bytes > max_payload_bytes:
raise SystemExit("desktop_bridge_archive_exceeds_size_limit")
archive.extractall(payload_dir, members=members, filter="data")
PY
if [ ! -f "$MANIFEST_PATH" ] || [ -L "$MANIFEST_PATH" ]; then
echo "::error::Desktop Bridge archive must place one regular payload-manifest.json at its extraction root."
exit 1
fi
if find "$PAYLOAD_DIR" -type l -print -quit | grep -q .; then
echo "::error::Desktop Bridge artifact must not contain symbolic links."
exit 1
fi
printf '%s %s\n' "$MANIFEST_SHA256" "$MANIFEST_PATH" | shasum -a 256 -c -
PAYLOAD_SHA256_NORMALIZED="$(printf '%s' "$PAYLOAD_SHA256" | tr '[:upper:]' '[:lower:]')"
MANIFEST_SHA256_NORMALIZED="$(printf '%s' "$MANIFEST_SHA256" | tr '[:upper:]' '[:lower:]')"
{
echo "EVAOS_DESKTOP_BRIDGE_PAYLOAD_DIR=$PAYLOAD_DIR"
echo "EVAOS_DESKTOP_BRIDGE_PAYLOAD_SHA256=$PAYLOAD_SHA256_NORMALIZED"
echo "EVAOS_DESKTOP_BRIDGE_MANIFEST_SHA256=$MANIFEST_SHA256_NORMALIZED"
} >> "$GITHUB_ENV"
echo "Pinned Desktop Bridge payload manifest identity verified."

- name: Install evaOS Mac-control helper (macOS only)
if: startsWith(matrix.platform, 'macos')
shell: bash
Expand Down Expand Up @@ -769,8 +900,6 @@ jobs:
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN || github.token }}
EVAOS_DESKTOP_BRIDGE_REQUIRE_REAL: '1'
EVAOS_DESKTOP_BRIDGE_SOURCE_REF: ${{ vars.EVAOS_DESKTOP_BRIDGE_SOURCE_REF }}
EVAOS_DESKTOP_BRIDGE_SOURCE_TOKEN: ${{ secrets.EVAOS_DESKTOP_BRIDGE_SOURCE_TOKEN || secrets.GH_TOKEN || secrets.GITHUB_TOKEN || github.token }}

- name: Validate macOS app staple inside DMG
if: startsWith(matrix.platform, 'macos')
Expand Down Expand Up @@ -932,6 +1061,7 @@ jobs:
startsWith(matrix.platform, 'macos')
shell: bash
run: |
set -euo pipefail
shopt -s nullglob
zips=(
out/evaOS\ Workbench-*-mac-*.zip
Expand All @@ -943,6 +1073,18 @@ jobs:
fi
printf 'Found macOS ZIP artifact(s):\n'
printf ' %s\n' "${zips[@]}"
for zip_path in "${zips[@]}"; do
extract_dir="$(mktemp -d "${RUNNER_TEMP}/evaos-updater-zip.XXXXXX")"
ditto -x -k "$zip_path" "$extract_dir"
apps=("$extract_dir"/*.app)
if [ "${#apps[@]}" -ne 1 ]; then
echo "::error::$zip_path must contain exactly one top-level signed Workbench app."
rm -rf "$extract_dir"
exit 1
fi
codesign --verify --deep --strict --verbose=2 "${apps[0]}"
rm -rf "$extract_dir"
done

- name: Write macOS arm64 updater metadata
if: >-
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ jobs:
skip_code_quality: true
macos_dmg_finalization: ${{ inputs.macos_dmg_finalization || 'local' }}
managed_resources_bundle: no-acp
desktop_bridge_payload_repository: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_REPOSITORY || 'electricsheephq/evaos-desktop-bridge' }}
desktop_bridge_payload_run_id: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_RUN_ID }}
desktop_bridge_payload_artifact_name: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_ARTIFACT_NAME || 'evaos-desktop-bridge-macos-arm64' }}
desktop_bridge_payload_sha256: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_SHA256 }}
desktop_bridge_manifest_sha256: ${{ vars.EVAOS_DESKTOP_BRIDGE_MANIFEST_SHA256 }}
matrix: >-
${{ (inputs.release_target_platforms || vars.EVAOS_RELEASE_TARGET_PLATFORMS || 'macos-arm64') == 'macos-arm64' && '{"include":[{"platform":"macos-arm64","os":"macos-15","command":"node scripts/build-with-builder.js arm64 --mac --arm64","artifact-name":"macos-build-arm64","arch":"arm64"}]}' || (inputs.release_target_platforms || vars.EVAOS_RELEASE_TARGET_PLATFORMS || 'macos-arm64') == 'macos' && '{"include":[{"platform":"macos-arm64","os":"macos-15","command":"node scripts/build-with-builder.js arm64 --mac --arm64","artifact-name":"macos-build-arm64","arch":"arm64"},{"platform":"macos-x64","os":"macos-15","command":"node scripts/build-with-builder.js x64 --mac --x64","artifact-name":"macos-build-x64","arch":"x64"}]}' || (inputs.release_target_platforms || vars.EVAOS_RELEASE_TARGET_PLATFORMS || 'macos-arm64') == 'windows' && '{"include":[{"platform":"windows-x64","os":"windows-2022","command":"node scripts/build-with-builder.js x64 --win --x64","artifact-name":"windows-build-x64","arch":"x64"},{"platform":"windows-arm64","os":"windows-11-arm","command":"node scripts/build-with-builder.js arm64 --win --arm64","artifact-name":"windows-build-arm64","arch":"arm64"}]}' || '{"include":[{"platform":"macos-arm64","os":"macos-15","command":"node scripts/build-with-builder.js arm64 --mac --arm64","artifact-name":"macos-build-arm64","arch":"arm64"},{"platform":"macos-x64","os":"macos-15","command":"node scripts/build-with-builder.js x64 --mac --x64","artifact-name":"macos-build-x64","arch":"x64"},{"platform":"windows-x64","os":"windows-2022","command":"node scripts/build-with-builder.js x64 --win --x64","artifact-name":"windows-build-x64","arch":"x64"},{"platform":"windows-arm64","os":"windows-11-arm","command":"node scripts/build-with-builder.js arm64 --win --arm64","artifact-name":"windows-build-arm64","arch":"arm64"},{"platform":"linux-x64","os":"ubuntu-latest","command":"node scripts/build-with-builder.js x64 --linux --x64","artifact-name":"linux-build-x64","arch":"x64"},{"platform":"linux-arm64","os":"ubuntu-24.04-arm","command":"node scripts/build-with-builder.js arm64 --linux --arm64","artifact-name":"linux-build-arm64","arch":"arm64"}]}' }}
secrets: inherit
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/build-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ jobs:
skip_code_quality: ${{ inputs.skip_code_quality }}
aioncore_run_id: ${{ inputs.aioncore_run_id }}
managed_resources_bundle: ${{ inputs.managed_resources_bundle }}
desktop_bridge_payload_repository: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_REPOSITORY || 'electricsheephq/evaos-desktop-bridge' }}
desktop_bridge_payload_run_id: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_RUN_ID }}
desktop_bridge_payload_artifact_name: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_ARTIFACT_NAME || 'evaos-desktop-bridge-macos-arm64' }}
desktop_bridge_payload_sha256: ${{ vars.EVAOS_DESKTOP_BRIDGE_PAYLOAD_SHA256 }}
desktop_bridge_manifest_sha256: ${{ vars.EVAOS_DESKTOP_BRIDGE_MANIFEST_SHA256 }}
append_commit_hash: true
upload_installers_only: true
secrets: inherit
Loading