mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-28 05:12:33 +00:00
Add package and publish workflow for Tauri app
This workflow automates the process of building, packaging, and publishing a Tauri application. It includes version extraction, release creation, and asset uploading for different platforms.
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
# 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
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
forceRelease:
|
||||
description: "Force release build even without publishing"
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
env:
|
||||
IS_ON_MASTER: ${{ github.ref == 'refs/heads/master' }}
|
||||
SHOULD_PUBLISH: ${{ github.ref == 'refs/heads/master' && vars.PUBLISH_REPO || '' }}
|
||||
PUBLISH_REPO: ${{ vars.PUBLISH_REPO }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
UPDATER_GIST_URL: ${{ secrets.UPDATER_GIST_URL }}
|
||||
UPDATER_GIST_ID: ${{ secrets.UPDATER_GIST_ID }}
|
||||
|
||||
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
|
||||
|
||||
- name: Extract version and tag
|
||||
id: extract-version
|
||||
run: |
|
||||
PACKAGE_VERSION=$(grep -m1 '^version' tauri/Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
TAG_NAME="air_v${PACKAGE_VERSION}"
|
||||
RELEASE_NAME="Telegram Air 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
|
||||
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-master branches or when publishing is disabled, always continue
|
||||
if [ -z "$SHOULD_PUBLISH" ]; then
|
||||
echo "🚧 Publishing disabled (non-master branch or PUBLISH_REPO not set)"
|
||||
echo "should-skip=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Checking if release already exists for tag: $TAG_NAME"
|
||||
|
||||
RESPONSE=$(curl -s -H "Authorization: token $GH_TOKEN" \
|
||||
"https://api.github.com/repos/$PUBLISH_REPO/releases/tags/$TAG_NAME")
|
||||
|
||||
if echo "$RESPONSE" | jq -e '.tag_name' > /dev/null; then
|
||||
IS_DRAFT=$(echo "$RESPONSE" | 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]
|
||||
if: needs.get-version.outputs.should-publish != '' && needs.check-version.outputs.should-skip != 'true'
|
||||
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 }}
|
||||
run: |
|
||||
echo "Creating draft release for tag: $TAG_NAME"
|
||||
echo "Repository: $PUBLISH_REPO"
|
||||
RESPONSE=$(curl -X POST \
|
||||
-H "Authorization: token $GH_TOKEN" \
|
||||
-d '{"tag_name": "'"$TAG_NAME"'", "name": "'"$RELEASE_NAME"'", "draft": true}' \
|
||||
"https://api.github.com/repos/$PUBLISH_REPO/releases")
|
||||
RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id')
|
||||
echo "Extracted Release ID: $RELEASE_ID"
|
||||
if [ "$RELEASE_ID" = "null" ]; then
|
||||
echo "Error: Failed to create release. Response was: $RESPONSE"
|
||||
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' }}
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- platform: "macos-latest"
|
||||
args: "--target aarch64-apple-darwin"
|
||||
- platform: "macos-latest"
|
||||
args: "--target x86_64-apple-darwin"
|
||||
- platform: "ubuntu-22.04"
|
||||
args: ""
|
||||
runs-on: ${{ matrix.settings.platform }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- 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
|
||||
|
||||
- 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: 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 moduleUrl = `file:///${workspacePath}/deploy/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, package and publish
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
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 }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
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' }}
|
||||
with:
|
||||
args: "-c ${{ steps.config-overrides.outputs.json }} ${{ matrix.settings.args }}"
|
||||
includeDebug: ${{ needs.get-version.outputs.should-publish == '' && inputs.forceRelease != 'true' }}
|
||||
includeRelease: ${{ needs.get-version.outputs.should-publish != '' || inputs.forceRelease == 'true' }}
|
||||
releaseId: ${{ needs.create-release.outputs.releaseId }}
|
||||
owner: ${{ steps.repository-info.outputs.owner }}
|
||||
repo: ${{ steps.repository-info.outputs.repo }}
|
||||
|
||||
- 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="${FILENAME%.*}"
|
||||
FILE_PATH=$(cd "$(dirname "$FULL_PATH")" && pwd)
|
||||
ARCHITECTURE=$(echo "${{ matrix.settings.args }}" | grep -oE 'x86_64|aarch64' || echo "")
|
||||
echo "name=$NAME" >> $GITHUB_OUTPUT
|
||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
||||
echo "architecture=$ARCHITECTURE" >> $GITHUB_OUTPUT
|
||||
echo "path=$FILE_PATH" >> $GITHUB_OUTPUT
|
||||
|
||||
# MacOS release — use the DMG produced by tauri-action directly
|
||||
- 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 $GH_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]
|
||||
if: needs.get-version.outputs.should-publish != '' && needs.check-version.outputs.should-skip != 'true'
|
||||
env:
|
||||
RELEASE_ID: ${{ needs.create-release.outputs.releaseId }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Publish release
|
||||
run: |
|
||||
curl -X PATCH -H "Authorization: Bearer $GH_TOKEN" -d '{"draft": false}' "https://api.github.com/repos/$PUBLISH_REPO/releases/$RELEASE_ID"
|
||||
|
||||
- name: Update Gist with JSON
|
||||
run: |
|
||||
ASSET_ID=$(curl -s -H "Authorization: Bearer $GH_TOKEN" "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: token $GH_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: token $GH_TOKEN" -d "$GIST_CONTENT" "https://api.github.com/gists/$UPDATER_GIST_ID"
|
||||
Reference in New Issue
Block a user