diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a934ce21..b20cfb19 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,13 +5,17 @@ on: inputs: version_bump: description: Version increment - required: true + required: false default: patch type: choice options: - major - minor - patch + release_version: + description: Build or rebuild this version from the selected ref + required: false + type: string push: branches: [main] @@ -33,7 +37,7 @@ env: jobs: create-version-pr: - if: ${{ github.event_name == 'workflow_dispatch' }} + if: ${{ github.event_name == 'workflow_dispatch' && inputs.release_version == '' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -81,7 +85,7 @@ jobs: gh pr create --base main --head "$BRANCH" --label release --title "chore: prepare release v${VERSION}" --body "Automated version bump for release v${VERSION}. Merge this PR to trigger the release workflow." detect-release: - if: ${{ github.event_name == 'push' }} + if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.release_version != '') }} runs-on: ubuntu-latest outputs: should_release: ${{ steps.detect.outputs.should_release }} @@ -95,13 +99,26 @@ jobs: shell: bash env: GH_TOKEN: ${{ github.token }} + RELEASE_VERSION: ${{ inputs.release_version }} run: | set -euo pipefail version="$(node -p "require('./package.json').version")" - release_pr="$(gh api --paginate "/repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" --jq '.[] | select(.base.ref == "main" and (.title | startswith("chore: prepare release v")) and (.head.ref | startswith("release/v"))) | .number' | head -n 1 || true)" - if [[ -z "$release_pr" ]]; then - echo 'should_release=false' >> "$GITHUB_OUTPUT" - exit 0 + if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then + requested_version="$RELEASE_VERSION" + if [[ ! "$requested_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ || "$requested_version" != "$version" ]]; then + echo "::error::Requested release version $requested_version does not match package.json version $version" + exit 1 + fi + if git rev-parse --quiet --verify "refs/tags/v${requested_version}" >/dev/null; then + echo "::error::Tag v${requested_version} already exists; refusing to replace an existing release" + exit 1 + fi + else + release_pr="$(gh api --paginate "/repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" --jq '.[] | select(.base.ref == "main" and (.title | startswith("chore: prepare release v")) and (.head.ref | startswith("release/v"))) | .number' | head -n 1 || true)" + if [[ -z "$release_pr" ]]; then + echo 'should_release=false' >> "$GITHUB_OUTPUT" + exit 0 + fi fi [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit 1 echo 'should_release=true' >> "$GITHUB_OUTPUT" diff --git a/bun.lock b/bun.lock index 7ac6181d..d494ff1c 100644 --- a/bun.lock +++ b/bun.lock @@ -45,7 +45,7 @@ "@typescript-eslint/parser": "^8.72.0", "@vitest/coverage-v8": "^5.0.5", "drizzle-kit": "^0.31.11", - "electron": "^45.0.0", + "electron": "^44.10.0", "electron-builder": "^26.18.0", "eslint": "^10.13.0", "eslint-config-next": "^16.4.2", @@ -1259,7 +1259,7 @@ "ejs": ["ejs@3.1.10", "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - "electron": ["electron@45.0.0", "https://registry.npmmirror.com/electron/-/electron-45.0.0.tgz", { "dependencies": { "@electron-internal/extract-zip": "^1.0.1", "@electron/get": "^5.0.0", "@types/node": "^24.9.0" }, "bin": { "electron": "cli.js", "install-electron": "install.js" } }, "sha512-yjz4uhMBcO6L5X7CWgRMobf2EMJPnb9j4zuf+nu/TU/6E4Sqfx7fn/a2eACo4qngjml/0JnsoZhxYroJLxLd2w=="], + "electron": ["electron@44.10.0", "https://registry.npmmirror.com/electron/-/electron-44.10.0.tgz", { "dependencies": { "@electron-internal/extract-zip": "^1.0.1", "@electron/get": "^5.0.0", "@types/node": "^24.9.0" }, "bin": { "electron": "cli.js", "install-electron": "install.js" } }, "sha512-ss4pCfrQKV4TWkuVYtWB4HmeysPZgB96cSYNKYZv1UVCRP4vQMGNW5oopFbvx6Bbfce1XtP5pm5RDuKehp0svQ=="], "electron-builder": ["electron-builder@26.18.0", "https://registry.npmmirror.com/electron-builder/-/electron-builder-26.18.0.tgz", { "dependencies": { "app-builder-lib": "26.18.0", "builder-util": "26.16.0", "builder-util-runtime": "9.7.0", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.18.0", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "./cli.js", "install-app-deps": "./install-app-deps.js" } }, "sha512-ASgIuQnOq4RuD8jMhS9hI0LS3EMRT1I/M5R6utqifB/BHN80IcCjBdt+DED+NmNPvmBgEtrlExXZitNdA7kXOg=="], diff --git a/e2e/desktop/settings.spec.ts b/e2e/desktop/settings.spec.ts index 707f53ff..1a62641a 100644 --- a/e2e/desktop/settings.spec.ts +++ b/e2e/desktop/settings.spec.ts @@ -70,7 +70,9 @@ test.describe('Desktop settings', () => { // disabled entry in it is not a menu. await expect(page.locator('#desktopStorageBackend')).toHaveCount(0); await expect(page.getByText('Storage backend')).toHaveCount(0); - await expect(page.getByText('Desktop app')).toBeVisible(); + await expect( + page.getByRole('heading', { name: 'Desktop app' }), + ).toBeVisible(); }); test('leaves the appearance and the language to the menu bar item', async ({ diff --git a/package.json b/package.json index 02989822..bd3e206a 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@typescript-eslint/parser": "^8.72.0", "@vitest/coverage-v8": "^5.0.5", "drizzle-kit": "^0.31.11", - "electron": "^45.0.0", + "electron": "^44.10.0", "electron-builder": "^26.18.0", "eslint": "^10.13.0", "eslint-config-next": "^16.4.2",