Files
openhuman/.github/workflows/package-and-publish.yml
T
Steven EnamakelandGitHub 37991fc567 refactor: split tauri host from openhuman_core runtime (#43)
* chore: add Cargo.toml and Cargo.lock for rust-core workspace

- Introduced a new workspace for the rust-core module with its own Cargo.toml.
- Added Cargo.lock to manage dependencies for the rust-core module.
- Updated .gitignore to exclude the target directory generated by Cargo.
- Modified GitHub Actions workflow to build from the new rust-core path instead of src-tauri.

* feat: enhance memory and authentication models in rust-core

- Added new `memory` module to handle persistent memory operations for skills, including methods for storing and querying skill data.
- Introduced `models` module with `auth` and `socket` submodules to manage user session and socket connection states.
- Updated `lib.rs` to include new modules and ensure proper integration within the rust-core workspace.
- Modified `eslint.config.js` to ignore target directories in linting processes.

* feat: integrate Tauri and QuickJS support in rust-core

- Added `tauri` and `rquickjs` as optional dependencies in `Cargo.toml` to enable Tauri integration and JavaScript execution.
- Introduced `CronScheduler` and `PingScheduler` modules for managing scheduled tasks and health checks for skills.
- Implemented `MemoryState` struct for shared app-state management in the memory client.
- Updated the runtime module to include new schedulers and ensure proper integration with Tauri features.
- Enhanced the skill registry to support new functionalities related to skill management and communication.

* chore: update ESLint configuration and refactor Rust module imports

- Added 'rust-core/**' to ESLint ignore list to streamline linting processes.
- Refactored import paths in Rust modules to directly reference the `memory` module, enhancing clarity and maintainability.
- Improved formatting in JavaScript files for better readability and consistency.

* refactor: rename rust-core to openhuman-core and update dependencies

- Renamed the `rust-core` module to `openhuman-core` across all files for consistency.
- Updated `Cargo.lock` to include `openhuman-core` as a new dependency and removed `rust-core`.
- Adjusted import paths in the codebase to reflect the new module name, ensuring all references are updated.
- Enhanced the Tauri integration by modifying dependencies in `src-tauri/Cargo.toml` to point to `openhuman-core`.

* refactor: simplify platform detection using match statements

- Replaced multiple if-else statements with match expressions in `current_platform`, `get_platform`, and `register` functions for improved readability and maintainability.
- Removed unnecessary conditional compilation for Android and iOS in the `SocketManager` and `tauri_bridge` modules, streamlining the codebase.
- Enhanced the `send_notification` function to handle platform checks more efficiently.

* refactor: update platform detection to use std::env::consts

- Replaced `cfg!(target_os = "os_name")` checks with `std::env::consts::OS` for improved clarity and consistency across the codebase.
- Added `rppal` as an optional dependency in `Cargo.toml` for Raspberry Pi support.
- Cleaned up platform-specific code in various modules, enhancing maintainability.

* refactor: streamline platform-specific code and improve readability

- Replaced conditional compilation with `std::env::consts::OS` checks in various modules to enhance clarity and maintainability.
- Simplified platform detection logic in `available_disk_space_mb`, `ensure_arduino_cli`, and `open_in_brave` functions.
- Updated `screenshot_command_exists` test to conditionally skip based on the operating system.
- Cleaned up unnecessary `#[cfg]` attributes, focusing on a more consistent approach across the codebase.

* feat: introduce comprehensive AI configuration and memory management

- Added multiple configuration files for OpenHuman AI, including `AGENTS.md`, `BOOTSTRAP.md`, `CONSCIOUS_LOOP.md`, `IDENTITY.md`, `MEMORY.md`, `README.md`, `SOUL.md`, `TOOLS.md`, and `USER.md` to define agent roles, onboarding processes, identity, memory management, and tool capabilities.
- Implemented an encryption layer for AI memory storage in `encryption.rs`, utilizing AES-256-GCM for secure data handling.
- Updated `lib.rs` to include the new AI module structure, enhancing the overall architecture and maintainability of the codebase.

* refactor: update dependencies and configuration for improved structure

- Removed `android_logger` and related packages from `Cargo.lock` and `Cargo.toml`, streamlining the dependency list.
- Adjusted the `APP_IDENTIFIER` constant in `config.rs` to reflect the new application identifier.
- Updated resource paths in `tauri.conf.json` for better organization.
- Enhanced platform-specific dependency management in `Cargo.toml` for clarity and maintainability.

* fix(core): gate ai module behind tauri-host feature

* refactor: update AI loading mechanisms and improve platform handling

- Refactored the AI configuration loading in `loader.ts` and `tools/loader.ts` to utilize Tauri commands for desktop environments, enhancing performance and reliability.
- Updated paths for AI markdown files to reflect the new `rust-core` structure.
- Introduced a new end-to-end test for Tauri command interactions in `tauriCoreBridge.e2e.test.ts`.
- Cleaned up platform-specific code across various modules, ensuring a more consistent approach to handling desktop and web contexts.

* feat: add sidecar core binary build and staging for Tauri bundler

- Implemented build steps for the sidecar core binary in multiple workflows, targeting both x86_64-unknown-linux-gnu and aarch64-apple-darwin architectures.
- Added staging steps to copy the built binaries into the Tauri resources directory, ensuring proper integration for application bundling.
- Updated relevant workflows to enhance the build process and streamline artifact management.

* refactor: enhance AI loading logic for Tauri integration

- Updated `loader.ts` and `tools/loader.ts` to prioritize Tauri commands for loading configurations in desktop environments, with a fallback to bundled markdown files for web contexts.
- Adjusted test mocks to reflect the new file paths for tools markdown.
- Improved test setup to mock Tauri API behavior accurately.

* docs: update CLAUDE.md and remove Android build scripts from package.json

- Added a new section in CLAUDE.md detailing the runtime scope, clarifying that Tauri is desktop-only and should not include mobile or web branches.
- Removed Android development and build scripts from package.json to streamline the project for desktop platforms only.

* refactor: streamline import statements and enhance test mock structure

- Reordered import statements in `loader.ts` and `tools/loader.ts` for consistency.
- Simplified mock implementation in `tauriCoreBridge.e2e.test.ts` to improve readability and maintainability.
- Added external binary configuration in `build.rs` to support resource management during local builds.

* test: stabilize core/unit test paths and tauri build-test config

* chore: update subproject commit reference in skills

* chore: update Tauri build configuration to include custom environment variable

- Modified the Tauri build command in the GitHub Actions workflow to set a custom configuration for updater artifacts, enhancing the build process for the x86_64-unknown-linux-gnu target.
2026-03-27 13:30:32 -07:00

500 lines
21 KiB
YAML

# Terms:
# "build" - Compile web project using webpack.
# "package" - Produce a distributive package for a specific platform as a workflow artifact.
# "publish" - Send a package to corresponding store and GitHub release page.
# "release" - build + package + publish
#
# Jobs in this workflow will skip the "publish" step when `SHOULD_PUBLISH` is not set.
name: Package and publish (Legacy)
on:
workflow_dispatch:
# pull_request:
# branches:
# - main
env:
IS_PR: ${{ github.event_name == 'pull_request' }}
SHOULD_PUBLISH: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/main' }}
PUBLISH_REPO: openhumanxyz/openhuman
XGH_TOKEN: ${{ secrets.XGH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
get-version:
runs-on: ubuntu-latest
outputs:
package-version: ${{ steps.extract-version.outputs.package-version }}
tag-name: ${{ steps.extract-version.outputs.tag-name }}
should-publish: ${{ steps.extract-version.outputs.should-publish }}
release-name: ${{ steps.extract-version.outputs.release-name }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
token: ${{ secrets.XGH_TOKEN_READ }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Extract version and tag
id: extract-version
run: |
PACKAGE_VERSION=$(node -p "require('./package.json').version")
TAG_NAME="v${PACKAGE_VERSION}"
RELEASE_NAME="OpenHuman v${PACKAGE_VERSION}"
echo "package-version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
echo "tag-name=$TAG_NAME" >> $GITHUB_OUTPUT
echo "release-name=$RELEASE_NAME" >> $GITHUB_OUTPUT
echo "should-publish=$SHOULD_PUBLISH" >> $GITHUB_OUTPUT
echo "Extracted version: $PACKAGE_VERSION"
echo "Generated tag: $TAG_NAME"
echo "Generated release name: $RELEASE_NAME"
check-version:
runs-on: ubuntu-latest
needs: get-version
environment: ${{ github.ref == 'refs/heads/main' && 'Production' || '' }}
outputs:
should-skip: ${{ steps.check-release.outputs.should-skip }}
steps:
- name: Check if release already exists
id: check-release
env:
PACKAGE_VERSION: ${{ needs.get-version.outputs.package-version }}
TAG_NAME: ${{ needs.get-version.outputs.tag-name }}
run: |
# For non-main branches or when publishing is disabled, always continue
if [ -z "$SHOULD_PUBLISH" ]; then
echo "🚧 Publishing disabled (non-main branch)"
echo "should-skip=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "Checking if release already exists for tag: $TAG_NAME"
RESPONSE=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$PUBLISH_REPO/releases/tags/$TAG_NAME")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "404" ]; then
echo "🆕 No release found for version $PACKAGE_VERSION, will create new release"
echo "should-skip=false" >> $GITHUB_OUTPUT
elif [ "$HTTP_CODE" != "200" ]; then
echo "⚠️ Warning: Failed to check release (HTTP $HTTP_CODE). Response: $BODY"
echo "Continuing anyway..."
echo "should-skip=false" >> $GITHUB_OUTPUT
elif echo "$BODY" | jq -e '.tag_name' > /dev/null; then
IS_DRAFT=$(echo "$BODY" | jq -r '.draft')
if [ "$IS_DRAFT" = "false" ]; then
echo "✅ Published release already exists for version $PACKAGE_VERSION"
echo "should-skip=true" >> $GITHUB_OUTPUT
else
echo "📝 Draft release exists for version $PACKAGE_VERSION, will continue"
echo "should-skip=false" >> $GITHUB_OUTPUT
fi
else
echo "🆕 No release found for version $PACKAGE_VERSION, will create new release"
echo "should-skip=false" >> $GITHUB_OUTPUT
fi
create-release:
runs-on: ubuntu-latest
needs: [get-version, check-version]
environment: ${{ github.ref == 'refs/heads/main' && 'Production' || '' }}
if: github.ref == 'refs/heads/main' && needs.get-version.outputs.should-publish == 'true' && needs.check-version.outputs.should-skip != 'true'
permissions:
contents: write
outputs:
releaseId: ${{ steps.create-release.outputs.releaseId }}
steps:
- name: Create draft release
id: create-release
env:
PACKAGE_VERSION: ${{ needs.get-version.outputs.package-version }}
TAG_NAME: ${{ needs.get-version.outputs.tag-name }}
RELEASE_NAME: ${{ needs.get-version.outputs.release-name }}
XGH_TOKEN: ${{ secrets.XGH_TOKEN }}
run: |
echo "Creating draft release for tag: $TAG_NAME"
echo "Repository: $PUBLISH_REPO"
RELEASE_BODY="See the assets below to download this version."
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
-H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d '{"tag_name": "'"$TAG_NAME"'", "name": "'"$RELEASE_NAME"'", "draft": true, "body": "'"$RELEASE_BODY"'"}' \
"https://api.github.com/repos/$PUBLISH_REPO/releases")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
echo "HTTP Status Code: $HTTP_CODE"
echo "Response body: $BODY"
if [ "$HTTP_CODE" != "201" ]; then
echo "Error: Failed to create release. HTTP $HTTP_CODE"
echo "Response: $BODY"
exit 1
fi
RELEASE_ID=$(echo "$BODY" | jq -r '.id')
echo "Extracted Release ID: $RELEASE_ID"
if [ "$RELEASE_ID" = "null" ] || [ -z "$RELEASE_ID" ]; then
echo "Error: Failed to extract release ID. Response was: $BODY"
exit 1
fi
echo "releaseId=$RELEASE_ID" >> $GITHUB_OUTPUT
package-tauri:
name: Build, package and publish Tauri
needs: [get-version, check-version, create-release]
if: ${{ !failure() && !cancelled() && needs.check-version.outputs.should-skip != 'true' }}
environment: ${{ github.ref == 'refs/heads/main' && 'Production' || '' }}
env:
GITHUB_TOKEN: ${{ secrets.XGH_TOKEN }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
settings:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
target: 'aarch64-apple-darwin'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
target: 'x86_64-apple-darwin'
- platform: 'ubuntu-22.04'
args: '--target x86_64-unknown-linux-gnu'
target: 'x86_64-unknown-linux-gnu'
runs-on: ${{ matrix.settings.platform }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: true
token: ${{ secrets.XGH_TOKEN_READ }}
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
- name: Set Xcode version
if: matrix.settings.platform == 'macos-latest'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: 'yarn'
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.settings.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Install Tauri dependencies (ubuntu only)
if: matrix.settings.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
# OpenMP is now disabled via Cargo.toml (default-features = false for llama-cpp-2)
# This avoids cross-compilation issues where Homebrew ARM64 OpenMP can't be used for x86_64 builds
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Cache Cargo build artifacts
uses: actions/cache@v4
with:
path: src-tauri/target
key: ${{ runner.os }}-cargo-target-${{ matrix.settings.platform }}-${{ hashFiles('src-tauri/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-target-${{ matrix.settings.platform }}-
- name: Cache node modules
id: yarn-cache
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install dependencies
if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Cache skills node modules
id: skills-yarn-cache
uses: actions/cache@v4
with:
path: skills/node_modules
key: ${{ runner.os }}-skills-${{ hashFiles('skills/yarn.lock') }}
restore-keys: |
${{ runner.os }}-skills-
- name: Install skills dependencies
if: steps.skills-yarn-cache.outputs.cache-hit != 'true'
run: cd skills && yarn install --frozen-lockfile
- name: Build skills
run: cd skills && yarn build
- name: Extract repository owner and name
id: repository-info
if: needs.get-version.outputs.should-publish != ''
shell: bash
run: |
echo "owner=${PUBLISH_REPO%%/*}" >> $GITHUB_OUTPUT
echo "repo=${PUBLISH_REPO#*/}" >> $GITHUB_OUTPUT
- name: Define Tauri configuration overrides
id: config-overrides
uses: actions/github-script@v7
env:
BASE_URL: ${{ vars.BASE_URL }}
UPDATER_PUBLIC_KEY: ${{ secrets.UPDATER_PUBLIC_KEY }}
WITH_UPDATER: ${{ needs.get-version.outputs.should-publish != '' && 'true' || 'false' }}
with:
script: |
const workspacePath = process.env.GITHUB_WORKSPACE.replace(/\\/g, '/');
const prefix = workspacePath.startsWith('/') ? 'file://' : 'file:///';
const moduleUrl = `${prefix}${workspacePath}/scripts/prepareTauriConfig.js`;
const { default: prepareTauriConfig } = await import(moduleUrl)
const config = prepareTauriConfig();
const configJson = JSON.stringify(config);
console.log(configJson);
core.setOutput("json", configJson);
- name: Build frontend
run: yarn build
env:
NODE_ENV: production
VITE_BACKEND_URL: ${{ vars.VITE_BACKEND_URL }}
VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }}
VITE_DEBUG: ${{ vars.VITE_DEBUG }}
- name: Build sidecar core binary
shell: bash
run: |
cargo build \
--manifest-path rust-core/Cargo.toml \
--release \
--target "$MATRIX_TARGET" \
--bin openhuman-core
env:
MATRIX_TARGET: ${{ matrix.settings.target }}
- name: Stage sidecar for Tauri bundler
shell: bash
run: |
mkdir -p src-tauri/binaries
SOURCE="rust-core/target/$MATRIX_TARGET/release/openhuman-core"
DEST="src-tauri/binaries/openhuman-core-$MATRIX_TARGET"
cp "$SOURCE" "$DEST"
chmod +x "$DEST"
env:
MATRIX_TARGET: ${{ matrix.settings.target }}
- name: Build, package and publish
uses: tauri-apps/tauri-action@v0.6.2
id: build-tauri
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
BASE_URL: ${{ vars.BASE_URL }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.UPDATER_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.UPDATER_PRIVATE_KEY_PASSWORD }}
WITH_UPDATER: ${{ needs.get-version.outputs.should-publish != '' && 'true' || 'false' }}
# macOS 10.15+ required for std::filesystem used by llama.cpp
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.settings.platform == 'macos-latest' && '10.15' || '' }}
with:
args: '-c ${{ steps.config-overrides.outputs.json }} ${{ matrix.settings.args }} -- -- --bin OpenHuman'
includeDebug: ${{ needs.get-version.outputs.should-publish == '' && inputs.forceRelease != 'true' }}
includeRelease: ${{ needs.get-version.outputs.should-publish != '' || inputs.forceRelease == 'true' }}
# TDLib dylibs are now bundled natively via build.rs + tauri.conf.json macOS.frameworks
# No post-build scripts needed - Tauri bundler handles copying and signing
releaseId: ${{ needs.create-release.outputs.releaseId }}
owner: openhumanxyz
repo: openhuman
- name: Get file info
id: file-info
shell: bash
run: |
FULL_PATH=$(echo "${{ fromJSON(steps.build-tauri.outputs.artifactPaths)[0] }}")
FILENAME=$(basename "$FULL_PATH")
NAME_WITH_EXT="${FILENAME%.*}"
VERSION="${{ needs.get-version.outputs.package-version }}"
TAG_NAME="${{ needs.get-version.outputs.tag-name }}"
# Remove version/tag patterns from name
# Patterns to remove: v0.14.0-1, 0.14.0-1, v0.14.0, 0.14.0, etc.
# Package managers add release numbers like -1, -2, etc.
NAME="$NAME_WITH_EXT"
# Remove version-release pattern (0.14.0-1, 0.14.0-2, etc.) - escape dots for regex
VERSION_ESCAPED=$(echo "$VERSION" | sed 's/\./\\./g')
NAME=$(echo "$NAME" | sed -E "s/[_-]?${VERSION_ESCAPED}-[0-9]+[_-]?//g")
# Remove tag-release pattern (v0.14.0-1, v0.14.0-2, etc.)
TAG_ESCAPED=$(echo "$TAG_NAME" | sed 's/\./\\./g')
NAME=$(echo "$NAME" | sed -E "s/[_-]?${TAG_ESCAPED}-[0-9]+[_-]?//g")
# Remove tag name (v0.14.0) with various separators
NAME=$(echo "$NAME" | sed -E "s/[_-]?${TAG_ESCAPED}[_-]?//g")
# Remove version (0.14.0) with various separators
NAME=$(echo "$NAME" | sed -E "s/[_-]?${VERSION_ESCAPED}[_-]?//g")
# Remove version with dots replaced by separators (0_14_0, 0-14-0)
VERSION_DASH=$(echo "$VERSION" | tr '.' '-')
VERSION_UNDERSCORE=$(echo "$VERSION" | tr '.' '_')
NAME=$(echo "$NAME" | sed -E "s/[_-]?v?${VERSION_DASH}[_-]?//g")
NAME=$(echo "$NAME" | sed -E "s/[_-]?v?${VERSION_UNDERSCORE}[_-]?//g")
# Clean up any double separators or trailing/leading separators
NAME=$(echo "$NAME" | sed -E 's/[_-]{2,}/_/g' | sed 's/^[_-]//' | sed 's/[_-]$//')
FILE_PATH=$(cd "$(dirname "$FULL_PATH")" && pwd)
# Extract architecture from target (e.g., aarch64-apple-darwin -> aarch64)
ARCHITECTURE=$(echo "${{ matrix.settings.target }}" | cut -d'-' -f1)
echo "name=$NAME" >> $GITHUB_OUTPUT
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
echo "architecture=$ARCHITECTURE" >> $GITHUB_OUTPUT
echo "path=$FILE_PATH" >> $GITHUB_OUTPUT
# MacOS release — upload the DMG after TDLib bundling and re-signing
- name: Upload release asset (MacOS)
if: matrix.settings.platform == 'macos-latest' && needs.get-version.outputs.should-publish != ''
shell: bash
run: |
SANITIZED_FILENAME=$(echo "${{ steps.file-info.outputs.name }}" | sed 's/ /./g')
PUBLISH_FILE_NAME="$SANITIZED_FILENAME-${{ steps.file-info.outputs.architecture }}.dmg"
FILE_PATH="${{ steps.file-info.outputs.path }}/${{ steps.file-info.outputs.filename }}"
RELEASE_ID="${{ needs.create-release.outputs.releaseId }}"
curl -X POST -H "Authorization: Bearer $XGH_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$FILE_PATH" \
"https://uploads.github.com/repos/$PUBLISH_REPO/releases/$RELEASE_ID/assets?name=$PUBLISH_FILE_NAME"
- name: Upload artifact (MacOS)
if: matrix.settings.platform == 'macos-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ steps.file-info.outputs.name }}-${{ steps.file-info.outputs.architecture }}.dmg
path: ${{ steps.file-info.outputs.path }}/${{ steps.file-info.outputs.filename }}
# Linux release
- name: Upload Linux artifact (Linux)
if: matrix.settings.platform == 'ubuntu-22.04'
uses: actions/upload-artifact@v4
with:
name: ${{ steps.file-info.outputs.filename }}
path: ${{ steps.file-info.outputs.path }}/${{ steps.file-info.outputs.filename }}
publish-release:
runs-on: ubuntu-latest
# needs: [get-version, check-version, create-release, package-tauri, package-android]
needs: [get-version, check-version, create-release, package-tauri]
environment: ${{ github.ref == 'refs/heads/main' && 'Production' || '' }}
if: github.ref == 'refs/heads/main' && needs.get-version.outputs.should-publish == 'true' && needs.check-version.outputs.should-skip != 'true'
permissions:
contents: write
env:
RELEASE_ID: ${{ needs.create-release.outputs.releaseId }}
XGH_TOKEN: ${{ secrets.XGH_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
- name: Publish release
run: |
RESPONSE=$(curl -s -w "\n%{http_code}" -X PATCH \
-H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d '{"draft": false}' \
"https://api.github.com/repos/$PUBLISH_REPO/releases/$RELEASE_ID")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" != "200" ]; then
echo "Error: Failed to publish release. HTTP $HTTP_CODE"
echo "Response: $BODY"
exit 1
fi
echo "Release published successfully"
- name: Update Gist with JSON
run: |
ASSET_ID=$(curl -s -H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$PUBLISH_REPO/releases/$RELEASE_ID/assets" | jq -r '.[] | select(.name == "latest.json") | .id')
JSON_CONTENT=$(curl -sSL -H "Accept: application/octet-stream" \
-H "Authorization: Bearer $XGH_TOKEN" \
"https://api.github.com/repos/$PUBLISH_REPO/releases/assets/$ASSET_ID")
GIST_CONTENT=$(jq -n --arg json "$JSON_CONTENT" '{"files":{"updater.json":{"content":$json}}}')
curl -X PATCH -H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d "$GIST_CONTENT" \
"https://api.github.com/gists/$UPDATER_GIST_ID"
delete-release-on-failure:
name: Delete draft release on build/publish failure
runs-on: ubuntu-latest
needs: [get-version, create-release, package-tauri, publish-release]
if: failure() && needs.create-release.result == 'success' && needs.create-release.outputs.releaseId != ''
permissions:
contents: write
env:
RELEASE_ID: ${{ needs.create-release.outputs.releaseId }}
TAG_NAME: ${{ needs.get-version.outputs.tag-name }}
XGH_TOKEN: ${{ secrets.XGH_TOKEN }}
steps:
- name: Delete draft release
run: |
echo "Deleting draft release $RELEASE_ID after build or publish failure"
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
-H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$PUBLISH_REPO/releases/$RELEASE_ID")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" = "204" ] || [ "$HTTP_CODE" = "404" ]; then
echo "Release deleted (or already gone)"
else
echo "Warning: Delete release returned HTTP $HTTP_CODE. Response: $BODY"
fi
- name: Delete tag
run: |
echo "Deleting tag $TAG_NAME"
RESPONSE=$(curl -s -w "\n%{http_code}" -X DELETE \
-H "Authorization: Bearer $XGH_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$PUBLISH_REPO/git/refs/tags/$TAG_NAME")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
if [ "$HTTP_CODE" = "204" ] || [ "$HTTP_CODE" = "404" ]; then
echo "Tag deleted (or already gone)"
else
echo "Warning: Delete tag returned HTTP $HTTP_CODE"
fi