Merge pull request #102 from j4rviscmd/fix/save-status-stuck #7
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
| # https://github.com/tauri-apps/tauri-action | |
| name: Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| jobs: | |
| preflight: | |
| name: Preflight — check if release already exists | |
| permissions: | |
| contents: read | |
| runs-on: ubuntu-latest | |
| outputs: | |
| skip: ${{ steps.check.outputs.skip }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Check for existing tag/release v__VERSION__ | |
| id: check | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const cfgPath = path.join(process.cwd(), 'src-tauri', 'tauri.conf.json'); | |
| let version = ''; | |
| try { | |
| const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); | |
| version = cfg.version || ''; | |
| } catch (e) { | |
| core.info(`Failed reading ${cfgPath}: ${e.message}`); | |
| } | |
| if (!version) { | |
| try { | |
| const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8')); | |
| version = pkg.version || ''; | |
| } catch (e) { | |
| core.info(`Failed reading package.json: ${e.message}`); | |
| } | |
| } | |
| if (!version) { | |
| core.setFailed('Unable to determine version from src-tauri/tauri.conf.json or package.json'); | |
| return; | |
| } | |
| const tagName = `v${version}`; | |
| core.info(`Checking if tag or release exists for ${tagName} ...`); | |
| try { | |
| await github.rest.git.getRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: `tags/${tagName}`, | |
| }); | |
| core.info(`Tag ${tagName} already exists. Skipping release.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } catch (e) { | |
| if (e.status !== 404) throw e; | |
| } | |
| const releases = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 100, | |
| }); | |
| const found = releases.data.find(r => r.tag_name === tagName); | |
| if (found) { | |
| core.info(`Release with tag ${tagName} already exists. Skipping release.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } | |
| core.info(`OK: ${tagName} does not exist. Proceeding with release.`); | |
| core.setOutput('skip', 'false'); | |
| publish-tauri: | |
| needs: preflight | |
| if: needs.preflight.outputs.skip != 'true' | |
| permissions: | |
| contents: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: 'macos-latest' | |
| args: '--target aarch64-apple-darwin' | |
| - platform: 'macos-latest' | |
| args: '--target x86_64-apple-darwin' | |
| - platform: 'windows-latest' | |
| args: '--bundles nsis' | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| - name: Install Rust (stable) | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} | |
| - name: Cache Rust | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| src-tauri/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Install frontend dependencies | |
| run: npm ci | |
| - name: Build and publish with Tauri | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| with: | |
| tagName: v__VERSION__ | |
| releaseName: 'v__VERSION__' | |
| releaseBody: 'See the assets to download this version and install.' | |
| releaseDraft: false | |
| prerelease: false | |
| generateReleaseNotes: true | |
| includeUpdaterJson: true | |
| updaterJsonPreferNsis: true | |
| args: ${{ matrix.args }} | |
| upload-stable-assets: | |
| name: Upload fixed-name assets for README links | |
| needs: publish-tauri | |
| permissions: | |
| contents: write | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Upload fixed-name copies | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const cfg = JSON.parse(fs.readFileSync('src-tauri/tauri.conf.json', 'utf8')); | |
| const version = cfg.version; | |
| const tag = `v${version}`; | |
| const { data: release } = await github.rest.repos.getReleaseByTag({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag, | |
| }); | |
| // Mapping: versioned asset name pattern → fixed name | |
| const renames = [ | |
| { match: `_${version}_aarch64.dmg`, fixedName: 'Scripta_macOS_arm64.dmg' }, | |
| { match: `_${version}_x64.dmg`, fixedName: 'Scripta_macOS_x64.dmg' }, | |
| { match: `_${version}_x64-setup.exe`, fixedName: 'Scripta_Windows_x64-setup.exe' }, | |
| ]; | |
| // Remove old fixed-name assets if they exist from a previous run | |
| for (const { fixedName } of renames) { | |
| const existing = release.assets.find(a => a.name === fixedName); | |
| if (existing) { | |
| await github.rest.repos.deleteReleaseAsset({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| asset_id: existing.id, | |
| }); | |
| core.info(`Deleted old asset: ${fixedName}`); | |
| } | |
| } | |
| for (const { match, fixedName } of renames) { | |
| const asset = release.assets.find(a => a.name.endsWith(match)); | |
| if (!asset) { | |
| core.warning(`Asset matching *${match} not found, skipping ${fixedName}`); | |
| continue; | |
| } | |
| // Download the versioned asset | |
| const download = await github.rest.repos.getReleaseAsset({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| asset_id: asset.id, | |
| headers: { accept: 'application/octet-stream' }, | |
| }); | |
| // Upload with fixed name | |
| const uploadUrl = release.upload_url; | |
| await github.rest.repos.uploadReleaseAsset({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: release.id, | |
| name: fixedName, | |
| data: Buffer.from(download.data), | |
| }); | |
| core.info(`Uploaded ${fixedName} (from ${asset.name})`); | |
| } |