diff --git a/.github/workflows/release-client.yml b/.github/workflows/release-client.yml index d41b2317..012089fe 100644 --- a/.github/workflows/release-client.yml +++ b/.github/workflows/release-client.yml @@ -1,189 +1,22 @@ -# BetterDesk Desktop Client — full release artifacts -# Builds the independent betterdesk-desktop Rust core + Flutter shell. +# RETIRED — desktop clients are built and released in UNITRONIX/BetterDesk-Client. +# This monorepo imports signed GitHub Releases (generic agent / generator templates) +# and must not build betterdesk-desktop here (tree is archived as *_old). +# +# Historical workflow name kept so GitHub Actions UI shows the retirement clearly. name: Build & Release Desktop Client on: - push: - tags: - - 'v*' workflow_dispatch: - inputs: - version: - description: 'Version tag for a manual test build (e.g., v3.5.49)' - required: false - default: '' - type: string permissions: - contents: write - -env: - CLIENT_DIR: betterdesk-desktop + contents: read jobs: - build-windows: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - cache: true - - - name: Install Protobuf Compiler - run: choco install protoc -y - - - name: Install WiX Toolset - shell: pwsh - run: dotnet tool install --global wix - - - name: Setup Flutter - uses: subosito/flutter-action@v2 - with: - channel: stable - cache: true - - - name: Build Windows EXE and MSI - working-directory: ${{ env.CLIENT_DIR }} - run: python build.py build --target windows-x64 - - - name: Verify Windows release artifacts - shell: pwsh - run: | - $dist = "${{ env.CLIENT_DIR }}/dist" - $required = @("*.exe", "*.msi", "*portable.zip", "DESKTOP_CHECKSUMS.sha256") - foreach ($pattern in $required) { - if (-not (Get-ChildItem -Path $dist -Filter $pattern -File)) { - throw "Missing Windows desktop artifact: $pattern" - } - } - - - name: Upload Windows release artifacts - uses: actions/upload-artifact@v4 - with: - name: betterdesk-windows-x64 - path: | - ${{ env.CLIENT_DIR }}/dist/BetterDesk-Desktop-* - if-no-files-found: error - - build-linux: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - clang \ - cmake \ - ninja-build \ - pkg-config \ - libgtk-3-dev \ - libstdc++-12-dev \ - libwebkit2gtk-4.1-dev \ - libappindicator3-dev \ - librsvg2-dev \ - patchelf \ - libssl-dev \ - libayatana-appindicator3-dev \ - protobuf-compiler \ - rpm \ - dpkg-dev - - - name: Install AppImage tool - run: | - sudo curl -L \ - https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage \ - -o /usr/local/bin/appimagetool - sudo chmod +x /usr/local/bin/appimagetool - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - cache: true - - - name: Setup Flutter - uses: subosito/flutter-action@v2 - with: - channel: stable - cache: true - - - name: Build Linux DEB, RPM, AppImage and tar.gz - working-directory: ${{ env.CLIENT_DIR }} - env: - APPIMAGE_EXTRACT_AND_RUN: '1' - run: python build.py build --target linux-x64 - - - name: Verify Linux release artifacts - run: | - set -euo pipefail - dist="${{ env.CLIENT_DIR }}/dist" - for pattern in "*.deb" "*.rpm" "*.AppImage" "*.tar.gz" "DESKTOP_CHECKSUMS.sha256"; do - compgen -G "$dist/$pattern" >/dev/null || { - echo "Missing Linux desktop artifact: $pattern" >&2 - exit 1 - } - done - - - name: Upload Linux release artifacts - uses: actions/upload-artifact@v4 - with: - name: betterdesk-linux-x64 - path: | - ${{ env.CLIENT_DIR }}/dist/BetterDesk-Desktop-* - if-no-files-found: error - - release: - if: startsWith(github.ref, 'refs/tags/v') - needs: [build-windows, build-linux] + retired: runs-on: ubuntu-latest - permissions: - contents: write steps: - - name: Download all artifacts - uses: actions/download-artifact@v4 - - - name: Generate checksums + - name: Desktop builds moved to BetterDesk-Client run: | - find . -type f \( -name "*.exe" -o -name "*.msi" -o -name "*.deb" -o -name "*.rpm" -o -name "*.AppImage" -o -name "*.tar.gz" \) -print0 | - sort -z | - xargs -0 sha256sum > DESKTOP_CHECKSUMS.sha256 - cat DESKTOP_CHECKSUMS.sha256 - - - name: Upload desktop artifacts to product release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ github.ref_name }} - run: | - set -euo pipefail - for attempt in $(seq 1 120); do - if gh release view "$TAG_NAME" >/dev/null 2>&1; then - break - fi - if [ "$attempt" -eq 120 ]; then - echo "GitHub Release $TAG_NAME was not created within 20 minutes" >&2 - exit 1 - fi - sleep 10 - done - - gh release upload "$TAG_NAME" \ - betterdesk-windows-x64/* \ - betterdesk-linux-x64/* \ - DESKTOP_CHECKSUMS.sha256 \ - --clobber + echo "Desktop client CI lives in https://github.com/UNITRONIX/BetterDesk-Client" + echo "BetterDesk console imports signed releases; it does not build clients in this repo." diff --git a/.github/workflows/release-server.yml b/.github/workflows/release-server.yml index 902a80ce..5679c9a1 100644 --- a/.github/workflows/release-server.yml +++ b/.github/workflows/release-server.yml @@ -139,17 +139,41 @@ jobs: TAG_NAME: ${{ github.ref_name }} run: | set -euo pipefail - for attempt in $(seq 1 120); do - if gh release view "$TAG_NAME" >/dev/null 2>&1; then + + release_exists() { + local err + err=$(mktemp) + if gh release view "$TAG_NAME" >"$err" 2>&1; then + rm -f "$err" + return 0 + fi + echo "gh release view ${TAG_NAME} failed:" >&2 + cat "$err" >&2 + rm -f "$err" + return 1 + } + + # Prefer an existing release (version-bump / manual). If none appears + # after a short wait, create one from this tag so assets are not blocked + # by protected-main version-bump failures. + found=0 + for attempt in $(seq 1 18); do + if release_exists; then + found=1 break fi - if [ "$attempt" -eq 120 ]; then - echo "GitHub Release $TAG_NAME was not created within 20 minutes" >&2 - exit 1 - fi + echo "Release ${TAG_NAME} not visible yet (attempt ${attempt}/18); retrying in 10s..." sleep 10 done + if [ "$found" -ne 1 ]; then + echo "Creating GitHub Release ${TAG_NAME} (version-bump did not publish it in time)" + gh release create "$TAG_NAME" \ + --title "BetterDesk ${TAG_NAME#v}" \ + --notes "BetterDesk ${TAG_NAME#v} server artifacts." \ + --verify-tag + fi + gh release upload "$TAG_NAME" \ betterdesk-server-linux-amd64/betterdesk-server-linux-amd64 \ betterdesk-server-linux-amd64/betterdesk-server-linux-amd64.manifest.json \ diff --git a/.github/workflows/rust-security-ci.yml b/.github/workflows/rust-security-ci.yml index 3451de02..abd7542f 100644 --- a/.github/workflows/rust-security-ci.yml +++ b/.github/workflows/rust-security-ci.yml @@ -1,64 +1,22 @@ -# Tauri desktop clients — cargo audit on push/PR +# RETIRED — Tauri client crates are no longer in this monorepo. +# Cargo audit for desktop clients runs in UNITRONIX/BetterDesk-Client. +# +# Path filters previously matched archived trees / this workflow file and failed +# on missing working directories (rdclient-desktop, betterdesk-agent-client). + name: Rust Security CI on: - push: - branches: [main, dev] - paths: - - 'rdclient-desktop/src-tauri/**' - - 'betterdesk-agent-client/src-tauri/**' - - '.github/workflows/rust-security-ci.yml' - pull_request: - branches: [main, dev] - paths: - - 'rdclient-desktop/src-tauri/**' - - 'betterdesk-agent-client/src-tauri/**' - - '.github/workflows/rust-security-ci.yml' + workflow_dispatch: permissions: contents: read -# glib RUSTSEC-2024-0429: transitive via Tauri GTK3/webkit2gtk; no fix without stack migration. -env: - CARGO_AUDIT_IGNORE: RUSTSEC-2024-0429 - jobs: - cargo-audit-rdclient: - if: github.event_name != 'push' || !contains(github.event.head_commit.message, '[version-bump]') + retired: runs-on: ubuntu-latest - defaults: - run: - working-directory: rdclient-desktop/src-tauri steps: - - uses: actions/checkout@v4 - - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - cache: true - - - name: Install cargo-audit - run: cargo install cargo-audit --locked - - - name: cargo audit (rdclient-desktop) - run: cargo audit --ignore ${{ env.CARGO_AUDIT_IGNORE }} - - cargo-audit-agent-client: - if: github.event_name != 'push' || !contains(github.event.head_commit.message, '[version-bump]') - runs-on: ubuntu-latest - defaults: - run: - working-directory: betterdesk-agent-client/src-tauri - steps: - - uses: actions/checkout@v4 - - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - cache: true - - - name: Install cargo-audit - run: cargo install cargo-audit --locked - - - name: cargo audit (betterdesk-agent-client) - run: cargo audit --ignore ${{ env.CARGO_AUDIT_IGNORE }} + - name: Rust client audits moved to BetterDesk-Client + run: | + echo "cargo-audit for desktop clients lives in https://github.com/UNITRONIX/BetterDesk-Client" + echo "This workflow no longer runs on push/PR to BetterDesk." diff --git a/.github/workflows/version-bump-main.yml b/.github/workflows/version-bump-main.yml index 17bc217e..f88e4407 100644 --- a/.github/workflows/version-bump-main.yml +++ b/.github/workflows/version-bump-main.yml @@ -1,9 +1,11 @@ # ============================================================================= # BetterDesk — stable release on merge to main # ============================================================================= -# When a PR is merged into main, bump minor version (+0.1.0), tag vX.Y.Z, -# and publish a GitHub Release. Existing release-server and docker-publish -# workflows run on the new tag / release event. +# When a PR is merged into main, bump version, publish tag + GitHub Release from +# the bump commit, and open a PR to land VERSION files on protected main. +# Direct push to main is not used (branch protection: require pull request). +# +# release-server / docker-publish attach artifacts to the tag/release. # ============================================================================= name: Version Bump & Release (main) @@ -15,6 +17,7 @@ on: permissions: contents: write + pull-requests: write concurrency: group: stable-release-main @@ -22,7 +25,11 @@ concurrency: jobs: release-stable: - if: github.event.pull_request.merged == true + # Skip the auto version-bump PR itself to avoid recursive bumps. + if: | + github.event.pull_request.merged == true && + !startsWith(github.event.pull_request.head.ref, 'release/v') && + !contains(github.event.pull_request.title, '[version-bump]') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -55,30 +62,59 @@ jobs: node scripts/bump-version.js "${BUMP_ARGS[@]}" NEW_VERSION=$(cat VERSION | tr -d '\n') echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT" + echo "branch=release/v${NEW_VERSION}" >> "$GITHUB_OUTPUT" - - name: Commit version bump to main + - name: Commit version bump on release branch + id: commit env: NEW_VERSION: ${{ steps.bump.outputs.version }} + BUMP_BRANCH: ${{ steps.bump.outputs.branch }} run: | + set -euo pipefail git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add $(node scripts/bump-version.js --list-paths) if git diff --cached --quiet; then - echo "No version files changed — skipping release bump commit" + echo "No version files changed — tagging current main tip only" + echo "has_bump=false" >> "$GITHUB_OUTPUT" exit 0 fi + git checkout -B "$BUMP_BRANCH" git commit -m "chore: release version ${NEW_VERSION} [version-bump]" - git push origin HEAD:main + git push -u origin "HEAD:${BUMP_BRANCH}" --force + echo "has_bump=true" >> "$GITHUB_OUTPUT" - - name: Sync checkout to bumped main + - name: Open version-bump PR into main + if: steps.commit.outputs.has_bump == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEW_VERSION: ${{ steps.bump.outputs.version }} + BUMP_BRANCH: ${{ steps.bump.outputs.branch }} run: | - git fetch origin main --tags - git reset --hard origin/main + set -euo pipefail + if gh pr view "$BUMP_BRANCH" --base main --json number >/dev/null 2>&1; then + echo "PR for ${BUMP_BRANCH} already exists" + gh pr view "$BUMP_BRANCH" --base main --json url -q .url + exit 0 + fi + BODY="Automated stable version bump to ${NEW_VERSION} after merge to main. + +Tag v${NEW_VERSION} and the GitHub Release are created from this bump commit. +Merge this PR so VERSION on main matches the published tag. + +Do not remove the [version-bump] marker from the title (prevents recursive bumps). +Server/Docker asset workflows attach to the tag, not to this PR merge." + gh pr create \ + --base main \ + --head "$BUMP_BRANCH" \ + --title "chore: release version ${NEW_VERSION} [version-bump]" \ + --body "$BODY" - name: Create tag and GitHub Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} NEW_VERSION: ${{ steps.bump.outputs.version }} + HAS_BUMP: ${{ steps.commit.outputs.has_bump }} run: | set -euo pipefail TAG="v${NEW_VERSION}" @@ -97,6 +133,18 @@ jobs: echo "BetterDesk ${NEW_VERSION} stable release." > "$NOTES_FILE" fi + # Tag the bump commit when present; otherwise clean main tip + # (discard uncommitted local bump so tag SHA matches published VERSION). + if [ "${HAS_BUMP}" = "true" ]; then + git checkout "release/v${NEW_VERSION}" + else + git fetch origin main + git reset --hard origin/main + NEW_VERSION=$(tr -d '\n' < VERSION) + TAG="v${NEW_VERSION}" + echo "No bump commit — using VERSION on main (${NEW_VERSION})" + fi + if ! git rev-parse "$TAG" >/dev/null 2>&1; then git tag "$TAG" git push origin "$TAG" @@ -111,4 +159,5 @@ jobs: gh release create "$TAG" \ --title "BetterDesk ${NEW_VERSION}" \ - --notes-file "$NOTES_FILE" + --notes-file "$NOTES_FILE" \ + --verify-tag diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f667f1b..1da169ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ - Billing packages attach to device groups only; folders excluded; one manual group per device; org create seeds a default device group. +### Fixed +- CI on `main`: retired in-repo desktop release + Rust cargo-audit workflows (clients build + in BetterDesk-Client); Go Server release upload creates a release if version-bump cannot + publish one; stable version-bump opens a PR instead of direct-push to protected `main`. + --- ## [3.5.171] — 2026-10-18