426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
649 lines
30 KiB
YAML
649 lines
30 KiB
YAML
# ============================================================
|
|
# Master Release Orchestrator — elizaOS cross-platform release
|
|
# ============================================================
|
|
#
|
|
# Triggers:
|
|
# - Tag push (v*.*.*) on main or develop → full release
|
|
# - workflow_dispatch → manually chosen platforms / version
|
|
#
|
|
# Required secrets (grouped by platform):
|
|
#
|
|
# --- GitHub ---
|
|
# GITHUB_TOKEN (automatic)
|
|
#
|
|
# --- Desktop (Electrobun) ---
|
|
# CSC_LINK base64-encoded Developer ID Application .p12
|
|
# CSC_KEY_PASSWORD password for the .p12
|
|
# APPLE_ID Apple ID email for notarization
|
|
# APPLE_APP_SPECIFIC_PASSWORD app-specific password
|
|
# APPLE_TEAM_ID 10-char Apple Developer Team ID
|
|
# WINDOWS_SIGN_CERT_BASE64 Windows code-signing certificate (base64)
|
|
# WINDOWS_SIGN_CERT_PASSWORD Windows cert password
|
|
# WINDOWS_SIGN_TIMESTAMP_URL RFC 3161 timestamp server URL
|
|
# RELEASE_UPLOAD_KEY (optional) SSH key for release host upload
|
|
# RELEASE_HOST_FINGERPRINT (optional) SSH host fingerprint for release host
|
|
#
|
|
# --- Android ---
|
|
# ANDROID_KEYSTORE_BASE64 base64-encoded release keystore (.jks)
|
|
# ANDROID_KEYSTORE_PASSWORD keystore password
|
|
# ANDROID_KEY_ALIAS signing key alias
|
|
# ANDROID_KEY_PASSWORD signing key password
|
|
# PLAY_STORE_SERVICE_ACCOUNT_JSON (optional) base64 Play Store service account
|
|
#
|
|
# --- Apple (iOS + macOS App Store) ---
|
|
# APPLE_ID (shared with desktop)
|
|
# APPLE_TEAM_ID (shared with desktop)
|
|
# APPLE_APP_SPECIFIC_PASSWORD (shared with desktop)
|
|
# ITC_TEAM_ID App Store Connect team ID
|
|
# APP_STORE_APP_ID numeric App Store application ID
|
|
# MATCH_PASSWORD Fastlane Match passphrase
|
|
# MATCH_GIT_URL Fastlane Match git repo URL
|
|
# MATCH_GIT_BASIC_AUTHORIZATION base64 git credentials for Match repo
|
|
# MAS_CSC_LINK base64-encoded Mac App Store .p12
|
|
# MAS_CSC_KEY_PASSWORD password for macOS MAS .p12
|
|
# MAS_INSTALLER_CERT base64-encoded Mac installer certificate
|
|
# MAS_INSTALLER_KEY_PASSWORD installer cert password
|
|
# APP_STORE_API_KEY_ID App Store Connect API key ID
|
|
# APP_STORE_API_ISSUER_ID App Store Connect API issuer ID
|
|
# APP_STORE_API_KEY_P8 App Store Connect API private key content (.p8)
|
|
#
|
|
# ============================================================
|
|
|
|
name: Release All Platforms
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*.*.*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Version to release (e.g. 2.0.1 or 2.1.0-beta.3)"
|
|
required: true
|
|
type: string
|
|
channel:
|
|
description: "Release channel (auto-detected from version if not set)"
|
|
required: false
|
|
type: choice
|
|
options:
|
|
- auto
|
|
- stable
|
|
- beta
|
|
- canary
|
|
default: auto
|
|
platforms:
|
|
description: "Comma-separated platforms to build (all | desktop,android,apple,linux-os,npm)"
|
|
required: false
|
|
type: string
|
|
default: "all"
|
|
desktop_target:
|
|
description: "Desktop platform target"
|
|
required: false
|
|
type: choice
|
|
options:
|
|
- all
|
|
- macos
|
|
- windows
|
|
- linux
|
|
default: "all"
|
|
android_track:
|
|
description: "Android Play Store track"
|
|
required: false
|
|
type: choice
|
|
options:
|
|
- auto
|
|
- internal
|
|
- beta
|
|
- production
|
|
default: "auto"
|
|
apple_track:
|
|
description: "Apple distribution track"
|
|
required: false
|
|
type: choice
|
|
options:
|
|
- auto
|
|
- testflight
|
|
- app-store
|
|
default: "auto"
|
|
draft:
|
|
description: "Create GitHub release as draft"
|
|
required: false
|
|
type: boolean
|
|
default: true
|
|
|
|
concurrency:
|
|
group: release-all-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
# ─────────────────────────────────────────────
|
|
# 1. VALIDATE — parse version, detect channel,
|
|
# compute per-platform enable flags, create
|
|
# the GitHub draft release.
|
|
# ─────────────────────────────────────────────
|
|
validate:
|
|
name: Validate & Prepare Release
|
|
runs-on: ${{ fromJSON(vars.HETZNER_FLEET_ONLINE == 'false' && '["ubuntu-24.04"]' || '["self-hosted","hetzner-robot"]') }}
|
|
outputs:
|
|
version: ${{ steps.parse.outputs.version }}
|
|
channel: ${{ steps.parse.outputs.channel }}
|
|
tag: ${{ steps.parse.outputs.tag }}
|
|
android_track: ${{ steps.parse.outputs.android_track }}
|
|
android_version_code: ${{ steps.parse.outputs.android_version_code }}
|
|
apple_track: ${{ steps.parse.outputs.apple_track }}
|
|
build_desktop: ${{ steps.parse.outputs.build_desktop }}
|
|
build_android: ${{ steps.parse.outputs.build_android }}
|
|
build_apple: ${{ steps.parse.outputs.build_apple }}
|
|
build_linux_os: ${{ steps.parse.outputs.build_linux_os }}
|
|
build_npm: ${{ steps.parse.outputs.build_npm }}
|
|
draft: ${{ steps.parse.outputs.draft }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
|
|
- name: Parse version and compute parameters
|
|
id: parse
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# ── Determine version string ──────────────────────────────────
|
|
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_type }}" == "tag" ]]; then
|
|
RAW_VERSION="${{ github.ref_name }}"
|
|
RAW_VERSION="${RAW_VERSION#v}"
|
|
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
|
RAW_VERSION="${{ inputs.version }}"
|
|
else
|
|
echo "::error::This workflow only runs on tag pushes or workflow_dispatch. Got event: ${{ github.event_name }}"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Validate semver ───────────────────────────────────────────
|
|
if ! echo "$RAW_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
|
|
echo "::error::Version '$RAW_VERSION' is not valid semver (expected X.Y.Z or X.Y.Z-prerelease)"
|
|
exit 1
|
|
fi
|
|
VERSION="$RAW_VERSION"
|
|
TAG="v${VERSION}"
|
|
echo "Resolved version: $VERSION tag: $TAG"
|
|
|
|
# ── Detect channel ────────────────────────────────────────────
|
|
CHANNEL_OVERRIDE="${{ inputs.channel || 'auto' }}"
|
|
if [[ "$CHANNEL_OVERRIDE" != "auto" ]]; then
|
|
CHANNEL="$CHANNEL_OVERRIDE"
|
|
elif echo "$VERSION" | grep -qE '-(alpha|beta|rc|nightly)'; then
|
|
CHANNEL="canary"
|
|
else
|
|
CHANNEL="stable"
|
|
fi
|
|
echo "Channel: $CHANNEL"
|
|
|
|
# ── Android track ─────────────────────────────────────────────
|
|
ANDROID_TRACK_OVERRIDE="${{ inputs.android_track || 'auto' }}"
|
|
if [[ "$ANDROID_TRACK_OVERRIDE" != "auto" ]]; then
|
|
ANDROID_TRACK="$ANDROID_TRACK_OVERRIDE"
|
|
elif echo "$VERSION" | grep -qE '-(beta|rc)'; then
|
|
ANDROID_TRACK="internal"
|
|
else
|
|
ANDROID_TRACK="production"
|
|
fi
|
|
echo "Android track: $ANDROID_TRACK"
|
|
|
|
# ── Apple track ───────────────────────────────────────────────
|
|
APPLE_TRACK_OVERRIDE="${{ inputs.apple_track || 'auto' }}"
|
|
if [[ "$APPLE_TRACK_OVERRIDE" != "auto" ]]; then
|
|
APPLE_TRACK="$APPLE_TRACK_OVERRIDE"
|
|
elif echo "$VERSION" | grep -qE '-[a-zA-Z]'; then
|
|
APPLE_TRACK="testflight"
|
|
else
|
|
APPLE_TRACK="app-store"
|
|
fi
|
|
echo "Apple track: $APPLE_TRACK"
|
|
|
|
# ── Draft flag ────────────────────────────────────────────────
|
|
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
|
DRAFT="${{ inputs.draft }}"
|
|
else
|
|
DRAFT="true"
|
|
fi
|
|
echo "Draft: $DRAFT"
|
|
|
|
# ── Platform enable flags ─────────────────────────────────────
|
|
PLATFORMS="${{ inputs.platforms || 'all' }}"
|
|
if [[ "$PLATFORMS" == "all" ]]; then
|
|
BUILD_DESKTOP="true"
|
|
BUILD_ANDROID="true"
|
|
BUILD_APPLE="true"
|
|
BUILD_LINUX_OS="true"
|
|
BUILD_NPM="true"
|
|
else
|
|
BUILD_DESKTOP="false"
|
|
BUILD_ANDROID="false"
|
|
BUILD_APPLE="false"
|
|
BUILD_LINUX_OS="false"
|
|
BUILD_NPM="false"
|
|
IFS=',' read -ra PLATFORM_LIST <<< "$PLATFORMS"
|
|
for P in "${PLATFORM_LIST[@]}"; do
|
|
P="${P// /}"
|
|
case "$P" in
|
|
desktop) BUILD_DESKTOP="true" ;;
|
|
android) BUILD_ANDROID="true" ;;
|
|
apple) BUILD_APPLE="true" ;;
|
|
linux-os) BUILD_LINUX_OS="true" ;;
|
|
npm) BUILD_NPM="true" ;;
|
|
*) echo "::warning::Unknown platform '$P' — ignored" ;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# npm publish via release.yaml only runs on GitHub release events
|
|
# (it does not accept workflow_call). Disable it here so callers
|
|
# know it must be triggered by the release creation itself.
|
|
if [[ "$BUILD_NPM" == "true" ]]; then
|
|
echo "::notice::npm publish is handled automatically by release.yaml when a GitHub release is created. The npm job in this orchestrator is a no-op reminder."
|
|
fi
|
|
|
|
echo "Platforms — desktop=$BUILD_DESKTOP android=$BUILD_ANDROID apple=$BUILD_APPLE linux-os=$BUILD_LINUX_OS npm=$BUILD_NPM"
|
|
|
|
# ── Create or validate GitHub Release ────────────────────────
|
|
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
echo "GitHub release $TAG already exists — will upload to it."
|
|
else
|
|
DRAFT_FLAG=""
|
|
if [[ "$DRAFT" == "true" ]]; then
|
|
DRAFT_FLAG="--draft"
|
|
fi
|
|
PRERELEASE_FLAG=""
|
|
if [[ "$CHANNEL" != "stable" ]]; then
|
|
PRERELEASE_FLAG="--prerelease"
|
|
fi
|
|
gh release create "$TAG" \
|
|
--title "$TAG" \
|
|
--notes "elizaOS cross-platform release $TAG (channel: $CHANNEL)" \
|
|
$DRAFT_FLAG \
|
|
$PRERELEASE_FLAG
|
|
echo "Created GitHub release $TAG (draft=$DRAFT)"
|
|
fi
|
|
|
|
# ── Android version_code ─────────────────────────────────────
|
|
# Must exactly match the Node.js formula in android-release.yml
|
|
# so the sideload manifest references the same versionCode that
|
|
# was published to the Play Store.
|
|
ANDROID_VERSION_CODE=$(node - "$VERSION" <<'NODE'
|
|
const version = process.argv[2];
|
|
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+)(?:\.(\d+))?)?$/);
|
|
if (!match) { console.error('Invalid semver: ' + version); process.exit(1); }
|
|
const [, majorRaw, minorRaw, patchRaw, prerelease, prereleaseRaw = '0'] = match;
|
|
const major = Number(majorRaw);
|
|
const minor = Number(minorRaw);
|
|
const patch = Number(patchRaw);
|
|
const prereleaseNumber = Number(prereleaseRaw);
|
|
const channelOffsets = { alpha: 1000, beta: 3000, rc: 5000, nightly: 7000 };
|
|
const channelOffset = prerelease ? (channelOffsets[prerelease] ?? 8000) : 9000;
|
|
const code = major * 100000000 + minor * 1000000 + patch * 10000 + channelOffset + prereleaseNumber;
|
|
if (code > 2100000000) { console.error('versionCode ' + code + ' exceeds Play Store limit'); process.exit(1); }
|
|
console.log(code);
|
|
NODE
|
|
)
|
|
echo "Android version_code: $ANDROID_VERSION_CODE"
|
|
|
|
# ── Write outputs ─────────────────────────────────────────────
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "channel=$CHANNEL" >> "$GITHUB_OUTPUT"
|
|
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
echo "android_track=$ANDROID_TRACK" >> "$GITHUB_OUTPUT"
|
|
echo "android_version_code=$ANDROID_VERSION_CODE" >> "$GITHUB_OUTPUT"
|
|
echo "apple_track=$APPLE_TRACK" >> "$GITHUB_OUTPUT"
|
|
echo "build_desktop=$BUILD_DESKTOP" >> "$GITHUB_OUTPUT"
|
|
echo "build_android=$BUILD_ANDROID" >> "$GITHUB_OUTPUT"
|
|
echo "build_apple=$BUILD_APPLE" >> "$GITHUB_OUTPUT"
|
|
echo "build_linux_os=$BUILD_LINUX_OS" >> "$GITHUB_OUTPUT"
|
|
echo "build_npm=$BUILD_NPM" >> "$GITHUB_OUTPUT"
|
|
echo "draft=$DRAFT" >> "$GITHUB_OUTPUT"
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 2. DESKTOP — Electrobun (macOS/Windows/Linux)
|
|
# ─────────────────────────────────────────────
|
|
desktop:
|
|
name: Desktop (Electrobun)
|
|
needs: validate
|
|
if: needs.validate.outputs.build_desktop == 'true'
|
|
uses: ./.github/workflows/release-electrobun.yml
|
|
with:
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
draft: ${{ needs.validate.outputs.draft == 'true' }}
|
|
publish_release: true
|
|
platform: ${{ inputs.desktop_target || 'all' }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 3. ANDROID
|
|
# ─────────────────────────────────────────────
|
|
android:
|
|
name: Android (Play Store)
|
|
needs: validate
|
|
if: needs.validate.outputs.build_android == 'true'
|
|
uses: ./.github/workflows/android-release.yml
|
|
with:
|
|
track: ${{ needs.validate.outputs.android_track }}
|
|
version_name: ${{ needs.validate.outputs.version }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 4. APPLE — iOS + macOS App Store
|
|
# ─────────────────────────────────────────────
|
|
apple:
|
|
name: Apple (iOS + macOS App Store)
|
|
needs: validate
|
|
if: needs.validate.outputs.build_apple == 'true'
|
|
uses: ./.github/workflows/apple-store-release.yml
|
|
with:
|
|
platform: "both"
|
|
track: ${{ needs.validate.outputs.apple_track }}
|
|
version: ${{ needs.validate.outputs.version }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 5. LINUX OS — ISO + .deb + VM image
|
|
#
|
|
# elizaos-os-full-release.yml does not accept
|
|
# workflow_call. Call the three leaf workflows
|
|
# directly, matching what the full-release
|
|
# orchestrator does internally.
|
|
# ─────────────────────────────────────────────
|
|
linux-os-iso:
|
|
name: Linux ISO
|
|
needs: validate
|
|
if: needs.validate.outputs.build_linux_os == 'true'
|
|
uses: ./.github/workflows/build-linux-iso.yml
|
|
with:
|
|
channel: ${{ needs.validate.outputs.channel == 'stable' && 'stable' || 'beta' }}
|
|
publish: true
|
|
secrets: inherit
|
|
|
|
linux-os-deb:
|
|
name: Linux .deb package
|
|
needs: validate
|
|
if: needs.validate.outputs.build_linux_os == 'true'
|
|
uses: ./.github/workflows/build-debian-package.yml
|
|
secrets: inherit
|
|
|
|
linux-os-vm:
|
|
name: Linux VM image
|
|
needs: validate
|
|
if: needs.validate.outputs.build_linux_os == 'true'
|
|
uses: ./.github/workflows/build-vm-image.yml
|
|
with:
|
|
format: "ova"
|
|
publish: true
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 6. NPM — reminder / gate
|
|
#
|
|
# release.yaml does NOT accept workflow_call.
|
|
# It fires automatically when a GitHub release
|
|
# is created (the event created by the validate
|
|
# job above). This job just documents that fact.
|
|
# ─────────────────────────────────────────────
|
|
npm:
|
|
name: npm packages (auto-triggered)
|
|
needs: validate
|
|
if: needs.validate.outputs.build_npm == 'true'
|
|
runs-on: ${{ fromJSON(vars.HETZNER_FLEET_ONLINE == 'false' && '["ubuntu-24.04"]' || '["self-hosted","hetzner-robot"]') }}
|
|
steps:
|
|
- name: Note — npm release auto-triggered
|
|
run: |
|
|
echo "## npm publish" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "The \`release.yaml\` workflow does not support \`workflow_call\`." >> "$GITHUB_STEP_SUMMARY"
|
|
echo "It is triggered automatically by the GitHub release creation in the" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "\`validate\` job above (event type: \`release: created\`)." >> "$GITHUB_STEP_SUMMARY"
|
|
echo "" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "No further action is needed for npm publishing." >> "$GITHUB_STEP_SUMMARY"
|
|
echo "npm publish for tag ${{ needs.validate.outputs.tag }} will be handled automatically by release.yaml"
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 7. SNAP — publish to Snap Store
|
|
# ─────────────────────────────────────────────
|
|
snap:
|
|
name: Snap Store
|
|
needs: validate
|
|
if: needs.validate.outputs.build_linux_os == 'true'
|
|
uses: ./.github/workflows/snap-publish.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
channel: ${{ needs.validate.outputs.channel == 'stable' && 'stable' || 'edge' }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 8. WINDOWS STORE — build + submit MSIX
|
|
# ─────────────────────────────────────────────
|
|
windows-store:
|
|
name: Windows Store (MSIX)
|
|
needs: [validate, desktop]
|
|
if: needs.validate.outputs.build_desktop == 'true' && needs.desktop.result == 'success'
|
|
uses: ./.github/workflows/windows-store-release.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
submit_to_store: true
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 9. ANDROID SIDELOAD MANIFEST — publish after
|
|
# Android build succeeds.
|
|
# version_code is computed in the validate job
|
|
# using the same Node.js formula as
|
|
# android-release.yml so the manifest always
|
|
# references the exact versionCode that was
|
|
# built and submitted to the Play Store.
|
|
# Called via workflow_call (not gh workflow run)
|
|
# so the orchestrator can track completion and
|
|
# surface failures in the summary job.
|
|
# ─────────────────────────────────────────────
|
|
android-update-manifest:
|
|
name: Android Sideload Manifest
|
|
needs: [validate, android]
|
|
if: needs.validate.outputs.build_android == 'true' && needs.android.result == 'success'
|
|
uses: ./.github/workflows/publish-android-update-manifest.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
version_code: ${{ needs.validate.outputs.android_version_code }}
|
|
channel: ${{ needs.validate.outputs.channel }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 10. AOSP MANIFEST — publish after Linux OS
|
|
# build succeeds.
|
|
# ─────────────────────────────────────────────
|
|
aosp-update-manifest:
|
|
name: AOSP Update Manifest
|
|
needs: [validate, linux-os-iso]
|
|
if: needs.validate.outputs.build_linux_os == 'true' && needs.linux-os-iso.result == 'success'
|
|
uses: ./.github/workflows/publish-aosp-update-manifest.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
channel: ${{ needs.validate.outputs.channel }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 11. APT REPO — publish .deb after Linux deb
|
|
# build succeeds.
|
|
# ─────────────────────────────────────────────
|
|
apt-repo:
|
|
name: apt Repository
|
|
needs: [validate, linux-os-deb]
|
|
if: needs.validate.outputs.build_linux_os == 'true' && needs.linux-os-deb.result == 'success'
|
|
uses: ./.github/workflows/publish-apt-repo.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
channel: ${{ needs.validate.outputs.channel == 'stable' && 'stable' || 'beta' }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 12. FLATPAK — submit to Flathub (if listed).
|
|
# The workflow self-guards: if the app is not
|
|
# yet listed on Flathub it warns and exits 0.
|
|
# ─────────────────────────────────────────────
|
|
flatpak:
|
|
name: Flathub
|
|
needs: validate
|
|
if: needs.validate.outputs.build_linux_os == 'true'
|
|
uses: ./.github/workflows/flatpak-publish.yml
|
|
with:
|
|
version: ${{ needs.validate.outputs.version }}
|
|
tag: ${{ needs.validate.outputs.tag }}
|
|
secrets: inherit
|
|
|
|
# ─────────────────────────────────────────────
|
|
# 13. SUMMARY — report all results; optionally
|
|
# publish the GitHub release draft.
|
|
# ─────────────────────────────────────────────
|
|
summary:
|
|
name: Release Summary
|
|
needs: [validate, desktop, android, apple, linux-os-iso, linux-os-deb, linux-os-vm, npm, snap, windows-store, android-update-manifest, aosp-update-manifest, apt-repo, flatpak]
|
|
if: always()
|
|
runs-on: ${{ fromJSON(vars.HETZNER_FLEET_ONLINE == 'false' && '["ubuntu-24.04"]' || '["self-hosted","hetzner-robot"]') }}
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
|
|
- name: Write step summary
|
|
run: |
|
|
VERSION="${{ needs.validate.outputs.version }}"
|
|
TAG="${{ needs.validate.outputs.tag }}"
|
|
CHANNEL="${{ needs.validate.outputs.channel }}"
|
|
|
|
result_icon() {
|
|
case "$1" in
|
|
success) echo "success" ;;
|
|
failure) echo "FAILURE" ;;
|
|
cancelled) echo "cancelled" ;;
|
|
skipped) echo "skipped" ;;
|
|
*) echo "$1" ;;
|
|
esac
|
|
}
|
|
|
|
# Compute aggregate linux-os result
|
|
ISO_R="${{ needs.linux-os-iso.result }}"
|
|
DEB_R="${{ needs.linux-os-deb.result }}"
|
|
VM_R="${{ needs.linux-os-vm.result }}"
|
|
LINUX_RESULT="success"
|
|
for R in "$ISO_R" "$DEB_R" "$VM_R"; do
|
|
if [[ "$R" == "failure" ]]; then LINUX_RESULT="FAILURE"; fi
|
|
if [[ "$R" == "cancelled" && "$LINUX_RESULT" != "FAILURE" ]]; then LINUX_RESULT="cancelled"; fi
|
|
done
|
|
|
|
{
|
|
echo "## elizaOS Cross-Platform Release — $TAG"
|
|
echo ""
|
|
echo "**Version:** \`$VERSION\` **Channel:** \`$CHANNEL\`"
|
|
echo ""
|
|
echo "| Platform | Result |"
|
|
echo "|----------|--------|"
|
|
echo "| Desktop (Electrobun) | $(result_icon '${{ needs.desktop.result }}') |"
|
|
echo "| Android | $(result_icon '${{ needs.android.result }}') |"
|
|
echo "| Apple (iOS + macOS) | $(result_icon '${{ needs.apple.result }}') |"
|
|
echo "| Linux ISO | $(result_icon "$ISO_R") |"
|
|
echo "| Linux .deb | $(result_icon "$DEB_R") |"
|
|
echo "| Linux VM image | $(result_icon "$VM_R") |"
|
|
echo "| npm (auto-triggered) | $(result_icon '${{ needs.npm.result }}') |"
|
|
echo "| Snap Store | $(result_icon '${{ needs.snap.result }}') |"
|
|
echo "| Windows Store (MSIX) | $(result_icon '${{ needs.windows-store.result }}') |"
|
|
echo "| Android sideload manifest | $(result_icon '${{ needs.android-update-manifest.result }}') |"
|
|
echo "| AOSP update manifest | $(result_icon '${{ needs.aosp-update-manifest.result }}') |"
|
|
echo "| apt repository | $(result_icon '${{ needs.apt-repo.result }}') |"
|
|
echo "| Flathub | $(result_icon '${{ needs.flatpak.result }}') |"
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Publish GitHub release (if all succeeded and not draft)
|
|
if: needs.validate.outputs.draft == 'false'
|
|
run: |
|
|
TAG="${{ needs.validate.outputs.tag }}"
|
|
DESKTOP_RESULT="${{ needs.desktop.result }}"
|
|
ANDROID_RESULT="${{ needs.android.result }}"
|
|
APPLE_RESULT="${{ needs.apple.result }}"
|
|
LINUX_ISO_RESULT="${{ needs.linux-os-iso.result }}"
|
|
LINUX_DEB_RESULT="${{ needs.linux-os-deb.result }}"
|
|
LINUX_VM_RESULT="${{ needs.linux-os-vm.result }}"
|
|
|
|
BUILD_DESKTOP="${{ needs.validate.outputs.build_desktop }}"
|
|
BUILD_ANDROID="${{ needs.validate.outputs.build_android }}"
|
|
BUILD_APPLE="${{ needs.validate.outputs.build_apple }}"
|
|
BUILD_LINUX_OS="${{ needs.validate.outputs.build_linux_os }}"
|
|
|
|
FAILED=0
|
|
check_result() {
|
|
local enabled="$1"
|
|
local result="$2"
|
|
local name="$3"
|
|
if [[ "$enabled" == "true" && "$result" != "success" && "$result" != "skipped" ]]; then
|
|
echo "::error::$name build result was '$result', expected success"
|
|
FAILED=1
|
|
fi
|
|
}
|
|
|
|
check_result "$BUILD_DESKTOP" "$DESKTOP_RESULT" "Desktop"
|
|
check_result "$BUILD_ANDROID" "$ANDROID_RESULT" "Android"
|
|
check_result "$BUILD_APPLE" "$APPLE_RESULT" "Apple"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_ISO_RESULT" "Linux ISO"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_DEB_RESULT" "Linux .deb"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_VM_RESULT" "Linux VM"
|
|
|
|
if [[ "$FAILED" -eq 0 ]]; then
|
|
echo "All enabled platform builds succeeded — publishing GitHub release $TAG..."
|
|
gh release edit "$TAG" --draft=false
|
|
echo "Release $TAG is now public."
|
|
else
|
|
echo "::error::One or more platform builds failed. GitHub release $TAG remains as draft."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Fail if any enabled platform failed
|
|
run: |
|
|
DESKTOP_RESULT="${{ needs.desktop.result }}"
|
|
ANDROID_RESULT="${{ needs.android.result }}"
|
|
APPLE_RESULT="${{ needs.apple.result }}"
|
|
LINUX_ISO_RESULT="${{ needs.linux-os-iso.result }}"
|
|
LINUX_DEB_RESULT="${{ needs.linux-os-deb.result }}"
|
|
LINUX_VM_RESULT="${{ needs.linux-os-vm.result }}"
|
|
|
|
BUILD_DESKTOP="${{ needs.validate.outputs.build_desktop }}"
|
|
BUILD_ANDROID="${{ needs.validate.outputs.build_android }}"
|
|
BUILD_APPLE="${{ needs.validate.outputs.build_apple }}"
|
|
BUILD_LINUX_OS="${{ needs.validate.outputs.build_linux_os }}"
|
|
|
|
FAILED=0
|
|
check_result() {
|
|
local enabled="$1"
|
|
local result="$2"
|
|
local name="$3"
|
|
if [[ "$enabled" == "true" && "$result" == "failure" ]]; then
|
|
echo "::error::$name failed (result: $result)"
|
|
FAILED=1
|
|
elif [[ "$enabled" == "true" && "$result" == "cancelled" ]]; then
|
|
echo "::warning::$name was cancelled"
|
|
FAILED=1
|
|
fi
|
|
}
|
|
|
|
check_result "$BUILD_DESKTOP" "$DESKTOP_RESULT" "Desktop"
|
|
check_result "$BUILD_ANDROID" "$ANDROID_RESULT" "Android"
|
|
check_result "$BUILD_APPLE" "$APPLE_RESULT" "Apple"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_ISO_RESULT" "Linux ISO"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_DEB_RESULT" "Linux .deb"
|
|
check_result "$BUILD_LINUX_OS" "$LINUX_VM_RESULT" "Linux VM"
|
|
|
|
exit "$FAILED"
|