fix: 修复 gmqtt 挂载导致 gmqttd 丢失,并发布离线镜像包 #16
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release — Build & Publish Installers | |
| on: | |
| push: | |
| tags: | |
| - 'v*.*.*' # 正式版本:v1.2.0 | |
| - 'v*.*.*.*' # 子版本:v1.1.13.6 | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "版本号(如 v1.2.0)" | |
| required: true | |
| type: string | |
| push_latest: | |
| description: "同时更新 latest 标签" | |
| required: false | |
| default: true | |
| type: boolean | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| REGISTRY: registry.cn-hangzhou.aliyuncs.com/thingspanel | |
| jobs: | |
| # ── 确定版本号 ────────────────────────────────────────────────────────────── | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| steps: | |
| - id: version | |
| name: Resolve version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ inputs.version }}" | |
| else | |
| VERSION="${GITHUB_REF_NAME}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "Version: ${VERSION}" | |
| # ── 验证 docker-compose.yml 语法 ─────────────────────────────────────────── | |
| validate: | |
| runs-on: ubuntu-latest | |
| needs: prepare | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Create test .env | |
| run: | | |
| cat > .env << 'EOF' | |
| POSTGRES_PASSWORD=test_pg_pass | |
| REDIS_PASSWORD=test_redis_pass | |
| AUTH_SECRET=test_auth_secret_minimum_32_chars_long | |
| TP_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_VUE_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_BACKEND_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_GMQTT_VERSION=v1.1.6 | |
| TP_REDIS_VERSION=6.2.7 | |
| TP_MODBUS_VERSION=v1.0.6.1 | |
| TP_HTTP_ADAPTER_VERSION=v1.0.0 | |
| TP_THINGSVIS_SERVER_VERSION=v1.0.4 | |
| TP_THINGSVIS_STUDIO_VERSION=v1.0.4 | |
| TP_TIMESCALEDB_VERSION=14 | |
| DATA_DIR=./data | |
| HTTP_PORT=8080 | |
| MQTT_PORT=1883 | |
| MODBUS_TCP_PORT=502 | |
| MODBUS_RTU_PORT=503 | |
| TZ=Asia/Shanghai | |
| TP_LOG_LEVEL=error | |
| EOF | |
| - name: Validate docker-compose syntax | |
| run: docker compose config --quiet | |
| - name: Check script syntax (bash) | |
| run: | | |
| bash -n install.sh | |
| bash -n upgrade.sh | |
| bash -n uninstall.sh | |
| # ── 构建 Windows 安装包 ───────────────────────────────────────────────────── | |
| # ── 镜像推送到 GHCR (可选) ────────────────────────────────────────────────── | |
| # ── 镜像推送到 GHCR (可选) 以及打包离线镜像 ────────────────────────────────── | |
| sync-ghcr-and-package: | |
| runs-on: ubuntu-latest | |
| needs: prepare | |
| permissions: | |
| packages: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Create .env | |
| run: | | |
| cat > .env << 'ENDEOF' | |
| POSTGRES_PASSWORD=1 | |
| REDIS_PASSWORD=1 | |
| AUTH_SECRET=1 | |
| TP_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_VUE_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_BACKEND_VERSION=${{ needs.prepare.outputs.version }} | |
| TP_GMQTT_VERSION=v1.1.6 | |
| TP_REDIS_VERSION=6.2.7 | |
| TP_MODBUS_VERSION=v1.0.6.1 | |
| TP_HTTP_ADAPTER_VERSION=v1.0.0 | |
| TP_THINGSVIS_SERVER_VERSION=v1.0.4 | |
| TP_THINGSVIS_STUDIO_VERSION=v1.0.4 | |
| TP_TIMESCALEDB_VERSION=14 | |
| DATA_DIR=./data | |
| DOCKER_REGISTRY=registry.cn-hangzhou.aliyuncs.com | |
| ENDEOF | |
| - name: Use Aliyun to list images | |
| run: | | |
| docker compose config --images > images.txt | |
| cat images.txt | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GHCR_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Pull and Push to GHCR | |
| run: | | |
| while read img; do | |
| docker pull "$img" | |
| if [[ "$img" == *"registry.cn-hangzhou.aliyuncs.com"* ]]; then | |
| ghcr_img=$(echo "$img" | sed 's/registry.cn-hangzhou.aliyuncs.com/ghcr.io/g') | |
| docker tag "$img" "$ghcr_img" | |
| docker push "$ghcr_img" || echo "Failed to push $ghcr_img but continuing..." | |
| else | |
| echo "Skip pushing $img to GHCR (not an Aliyun registry image)" | |
| fi | |
| done < images.txt | |
| - name: Package Offline Images | |
| run: | | |
| docker save $(cat images.txt) -o images.tar | |
| - name: Upload images.tar artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: docker-images-tar | |
| path: images.tar | |
| retention-days: 1 | |
| build-windows: | |
| runs-on: windows-latest | |
| needs: [prepare, validate, sync-ghcr-and-package] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Inno Setup | |
| run: choco install innosetup --no-progress -y | |
| - name: Create placeholder icon (if not exists) | |
| shell: pwsh | |
| run: | | |
| $iconDir = "packaging\windows\assets" | |
| if (-not (Test-Path "$iconDir\thingspanel.ico")) { | |
| Copy-Item "$env:SystemRoot\System32\shell32.dll" "$iconDir\thingspanel.ico" -ErrorAction SilentlyContinue || $true | |
| } | |
| if (-not (Test-Path "$iconDir\sidebar.bmp")) { | |
| [System.IO.File]::WriteAllBytes("$iconDir\sidebar.bmp", [byte[]]@(66,77,58,0,0,0,0,0,0,0,54,0,0,0,40,0,0,0,1,0,0,0,1,0,0,0,1,0,24,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0)) | |
| } | |
| - name: Download images.tar artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: docker-images-tar | |
| path: . | |
| - name: Build Windows installer | |
| shell: cmd | |
| env: | |
| TP_VERSION: ${{ needs.prepare.outputs.version }} | |
| run: | | |
| mkdir dist\windows 2>nul || true | |
| "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DTP_VERSION=%TP_VERSION% packaging\windows\ThingsPanel-Setup.iss | |
| - name: Upload Windows artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-installer | |
| path: dist/windows/ThingsPanel-Setup-*.exe | |
| retention-days: 7 | |
| build-macos: | |
| runs-on: macos-latest | |
| needs: [prepare, validate, sync-ghcr-and-package] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Create placeholder resources (if not exists) | |
| run: | | |
| mkdir -p packaging/macos/resources | |
| [ -f packaging/macos/resources/welcome.html ] || echo "<html><body><h2>欢迎安装 ThingsPanel</h2></body></html>" > packaging/macos/resources/welcome.html | |
| [ -f packaging/macos/resources/readme.html ] || echo "<html><body><h2>说明</h2><p>ThingsPanel 是一个开...</p></body></html>" > packaging/macos/resources/readme.html | |
| [ -f packaging/macos/resources/license.html ] || echo "<html><body><h2>许可证</h2><p>Apache 2.0</p></body></html>" > packaging/macos/resources/license.html | |
| [ -f packaging/macos/resources/conclusion.html ] || echo "<html><body><h2>安装完成</h2><p>访问 http://localhost:8080</p></body></html>" > packaging/macos/resources/conclusion.html | |
| [ -f packaging/macos/resources/background.png ] || echo "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" | base64 -d > packaging/macos/resources/background.png | |
| - name: Make scripts executable | |
| run: | | |
| chmod +x packaging/macos/build.sh | |
| chmod +x packaging/macos/scripts/preinstall | |
| chmod +x packaging/macos/scripts/postinstall | |
| - name: Download images.tar artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: docker-images-tar | |
| path: . | |
| - name: Build macOS installer | |
| env: | |
| TP_VERSION: ${{ needs.prepare.outputs.version }} | |
| run: ./packaging/macos/build.sh | |
| - name: Upload macOS artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-installer | |
| path: dist/macos/ThingsPanel-*.pkg | |
| retention-days: 7 | |
| release: | |
| runs-on: ubuntu-latest | |
| needs: [prepare, build-windows, build-macos] | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download Windows installer | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: windows-installer | |
| path: dist/windows | |
| - name: Download macOS installer | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: macos-installer | |
| path: dist/macos | |
| - name: Download offline images.tar | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: docker-images-tar | |
| path: dist | |
| - name: Generate SHA256 checksums | |
| run: | | |
| cd dist | |
| touch SHA256SUMS.txt | |
| find . -type f \( -name "*.exe" -o -name "*.pkg" -o -name "images.tar" \) | sort | while read f; do | |
| sha256sum "$f" >> SHA256SUMS.txt | |
| done | |
| cat SHA256SUMS.txt | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.version }} | |
| name: "ThingsPanel All-in-One ${{ needs.prepare.outputs.version }}" | |
| body: | | |
| ## ThingsPanel All-in-One ${{ needs.prepare.outputs.version }} | |
| ### 快速安装 | |
| **Linux / macOS(推荐)** | |
| ```bash | |
| curl -fsSL https://raw.githubusercontent.com/ThingsPanel/all-in-one-assembler/main/install.sh | sh | |
| ``` | |
| **Windows** | |
| 下载下方 `ThingsPanel-Setup-*.exe`,右键"以管理员身份运行"。 | |
| **macOS(图形界面)** | |
| 下载下方 `ThingsPanel-*.pkg`,双击安装。 | |
| ### 前置要求 | |
| - Docker Desktop(Windows / macOS)或 Docker Engine(Linux) | |
| - 内存 ≥ 2GB | |
| ### 文件说明 | |
| | 文件 | 平台 | 说明 | | |
| |------|------|------| | |
| | `ThingsPanel-Setup-*.exe` | Windows | Inno Setup 安装向导 | | |
| | `ThingsPanel-*.pkg` | macOS | macOS 安装包 | | |
| | `images.tar` | Windows/Linux/macOS | 离线 Docker 镜像包(可选,放到安装目录后会自动 `docker load`) | | |
| | `install.sh` | Linux/macOS | 一行命令安装脚本 | | |
| draft: false | |
| prerelease: ${{ contains(needs.prepare.outputs.version, 'rc') || contains(needs.prepare.outputs.version, 'beta') }} | |
| files: | | |
| dist/windows/*.exe | |
| dist/macos/*.pkg | |
| dist/images.tar | |
| dist/SHA256SUMS.txt |