Skip to content

【优化】桌面端依赖问题 #6

【优化】桌面端依赖问题

【优化】桌面端依赖问题 #6

Workflow file for this run

name: TaskBridge Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Release version, for example v0.1.4"
required: true
type: string
publish_latest:
description: "Also publish the Docker latest tag"
required: true
default: true
type: boolean
permissions:
contents: write
packages: write
concurrency:
group: release-${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
cancel-in-progress: false
env:
RELEASE_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
DOCKERHUB_IMAGE: ${{ vars.DOCKERHUB_IMAGE || '27xk/taskbridge' }}
TASKBRIDGE_BASE_URL: ${{ vars.TASKBRIDGE_BASE_URL || 'http://192.168.10.30:8000/api/v1/' }}
TASKBRIDGE_WS_URL: ${{ vars.TASKBRIDGE_WS_URL || 'ws://192.168.10.30:8000/ws/sync' }}
TASKBRIDGE_ALLOW_UNSIGNED_RELEASE: ${{ vars.TASKBRIDGE_ALLOW_UNSIGNED_RELEASE || 'false' }}
jobs:
prepare:
name: Prepare Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate release version
shell: bash
run: |
if [[ ! "${RELEASE_VERSION}" =~ ^v[0-9]+(\.[0-9]+){0,2}([-.][0-9A-Za-z.]+)?$ ]]; then
echo "::error::Release version must start with v, for example v0.1.4."
exit 1
fi
- name: Ensure release tag exists
if: ${{ github.event_name == 'workflow_dispatch' }}
shell: bash
run: |
git fetch --tags --force
if git rev-parse -q --verify "refs/tags/${RELEASE_VERSION}" >/dev/null; then
echo "Tag ${RELEASE_VERSION} already exists."
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag "${RELEASE_VERSION}" "${GITHUB_SHA}"
git push origin "refs/tags/${RELEASE_VERSION}"
fi
android:
name: Build Android APK
runs-on: ubuntu-latest
needs: prepare
defaults:
run:
working-directory: android
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-home-cache-cleanup: true
- name: Decode Android signing key
shell: bash
run: |
if [ -n "$ANDROID_KEYSTORE_BASE64" ]; then
echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > release.keystore
fi
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
- name: Validate Android signing secrets
shell: bash
run: |
missing=()
provided=()
for name in ANDROID_KEYSTORE_BASE64 ANDROID_KEYSTORE_PASSWORD ANDROID_KEY_ALIAS ANDROID_KEY_PASSWORD; do
if [ -z "${!name}" ]; then
missing+=("$name")
else
provided+=("$name")
fi
done
if [ "${#missing[@]}" -gt 0 ]; then
if [ "${#provided[@]}" -gt 0 ]; then
echo "Android signing secrets are partially configured. Missing: ${missing[*]}" >&2
exit 1
fi
if [ "${TASKBRIDGE_ALLOW_UNSIGNED_RELEASE}" = "true" ]; then
echo "::warning::Android signing secrets are not configured. Building an unsigned release APK because TASKBRIDGE_ALLOW_UNSIGNED_RELEASE=true."
exit 0
fi
echo "Missing Android signing secrets: ${missing[*]}" >&2
echo "Configure Android signing secrets, or set repository variable TASKBRIDGE_ALLOW_UNSIGNED_RELEASE=true to publish an unsigned APK." >&2
exit 1
fi
if [ ! -s release.keystore ]; then
echo "Decoded Android signing keystore is empty or missing." >&2
exit 1
fi
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
TASKBRIDGE_ALLOW_UNSIGNED_RELEASE: ${{ env.TASKBRIDGE_ALLOW_UNSIGNED_RELEASE }}
- name: Make Gradle wrapper executable
run: chmod +x gradlew
- name: Run unit tests
run: ./gradlew testReleaseUnitTest -PTASKBRIDGE_USE_CHINA_MIRRORS=false -PTASKBRIDGE_BASE_URL="${TASKBRIDGE_BASE_URL}" -PTASKBRIDGE_WS_URL="${TASKBRIDGE_WS_URL}" --stacktrace
- name: Build release APK
run: ./gradlew :app:assembleRelease -PTASKBRIDGE_USE_CHINA_MIRRORS=false -PTASKBRIDGE_BASE_URL="${TASKBRIDGE_BASE_URL}" -PTASKBRIDGE_WS_URL="${TASKBRIDGE_WS_URL}" --stacktrace
env:
ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android/release.keystore
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
TASKBRIDGE_ALLOW_UNSIGNED_RELEASE: ${{ env.TASKBRIDGE_ALLOW_UNSIGNED_RELEASE }}
- name: Prepare Android artifact
shell: bash
run: |
mkdir -p ../artifacts
find app/build/outputs/apk -maxdepth 3 -type f -print
apk_path="$(find app/build/outputs/apk/release -maxdepth 1 -type f \( -name 'app-release.apk' -o -name 'app-release-unsigned.apk' \) | head -n 1)"
if [ -z "$apk_path" ]; then
echo "No release APK was produced." >&2
exit 1
fi
cp "$apk_path" "../artifacts/TaskBridge-${RELEASE_VERSION}-android.apk"
- name: Upload Android artifact
uses: actions/upload-artifact@v4
with:
name: taskbridge-android
path: artifacts/*.apk
if-no-files-found: error
desktop:
name: Build Windows installer
runs-on: windows-latest
needs: prepare
defaults:
run:
working-directory: desktop
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: desktop/package-lock.json
- name: Install dependencies
run: npm ci
- name: Verify desktop endpoint config
run: npm run check:desktop-endpoint-config
- name: Verify security-sensitive config
run: npm run check:security-config
- name: Build Windows installer
run: npm run dist
env:
TASKBRIDGE_BASE_URL: ${{ env.TASKBRIDGE_BASE_URL }}
TASKBRIDGE_WS_URL: ${{ env.TASKBRIDGE_WS_URL }}
CSC_IDENTITY_AUTO_DISCOVERY: "false"
ELECTRON_CACHE: ${{ github.workspace }}\\.cache\\electron
ELECTRON_BUILDER_CACHE: ${{ github.workspace }}\\.cache\\electron-builder
- name: Prepare desktop artifacts
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path ..\artifacts | Out-Null
Get-ChildItem -Path release -Recurse -File | Select-Object FullName, Length
Get-ChildItem -Path release -File | Where-Object { $_.Extension -in '.exe', '.blockmap' } | ForEach-Object {
Copy-Item -LiteralPath $_.FullName -Destination ..\artifacts\$($_.Name)
}
- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: taskbridge-desktop
path: artifacts/*
if-no-files-found: error
docker:
name: Build and publish backend image
runs-on: ubuntu-latest
needs: prepare
outputs:
ghcr_image: ${{ steps.image.outputs.ghcr }}
dockerhub_image: ${{ steps.image.outputs.dockerhub }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Validate Docker Hub secrets
shell: bash
run: |
missing=()
for name in DOCKERHUB_USERNAME DOCKERHUB_TOKEN; do
if [ -z "${!name}" ]; then
missing+=("$name")
fi
done
if [ "${#missing[@]}" -gt 0 ]; then
echo "::error::Missing Docker Hub secrets: ${missing[*]}."
exit 1
fi
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Resolve image name
id: image
shell: bash
run: |
ghcr_image="ghcr.io/${GITHUB_REPOSITORY_OWNER}/taskbridge"
dockerhub_image="${DOCKERHUB_IMAGE}"
echo "ghcr=${ghcr_image,,}" >> "$GITHUB_OUTPUT"
echo "dockerhub=${dockerhub_image,,}" >> "$GITHUB_OUTPUT"
- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ steps.image.outputs.ghcr }}
${{ steps.image.outputs.dockerhub }}
tags: |
type=raw,value=${{ env.RELEASE_VERSION }}
type=raw,value=latest,enable=${{ github.event_name == 'push' || inputs.publish_latest == true }}
- name: Build and push backend image
uses: docker/build-push-action@v6
with:
context: ./backend
file: ./backend/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
release:
name: Update GitHub Release
runs-on: ubuntu-latest
needs:
- android
- desktop
- docker
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
pattern: taskbridge-*
merge-multiple: true
- name: List release artifacts
shell: bash
run: find release-artifacts -maxdepth 1 -type f -print
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.RELEASE_VERSION }}
name: TaskBridge ${{ env.RELEASE_VERSION }}
target_commitish: ${{ github.sha }}
generate_release_notes: true
files: release-artifacts/*
fail_on_unmatched_files: true
body: |
Backend Docker images:
- `${{ needs.docker.outputs.ghcr_image }}:${{ env.RELEASE_VERSION }}`
- `${{ needs.docker.outputs.dockerhub_image }}:${{ env.RELEASE_VERSION }}`
When `latest` is enabled, these tags are also published:
- `${{ needs.docker.outputs.ghcr_image }}:latest`
- `${{ needs.docker.outputs.dockerhub_image }}:latest`
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}