Generate Update JSON #10
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: Generate Update JSON | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'The release tag to generate update JSON for (e.g. v0.1.0)' | |
| required: true | |
| type: string | |
| jobs: | |
| create-update: | |
| permissions: | |
| contents: write | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v2 | |
| with: | |
| version: 8 | |
| run_install: false | |
| - name: Install Tauri CLI | |
| run: pnpm add -D @tauri-apps/cli | |
| - name: Install jq | |
| run: sudo apt-get install jq | |
| - name: Download release assets | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const artifacts = [ | |
| 'litepost_aarch64.app.tar.gz', | |
| 'litepost_x64.app.tar.gz', | |
| 'litepost_0.1.0_amd64.AppImage', | |
| 'litepost_0.1.0_x64-setup.exe' | |
| ]; | |
| const tag = '${{ inputs.tag }}'; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Get all releases including drafts | |
| const releases = await github.rest.repos.listReleases({ | |
| owner, | |
| repo, | |
| per_page: 100 | |
| }); | |
| // Find the release by tag, including drafts | |
| const release = releases.data.find(r => r.tag_name === tag); | |
| if (!release) { | |
| throw new Error('Release not found'); | |
| } | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| if (!fs.existsSync('artifacts')) { | |
| fs.mkdirSync('artifacts'); | |
| } | |
| for (const asset of release.assets) { | |
| if (artifacts.includes(asset.name)) { | |
| // Download using the GitHub API | |
| const response = await github.rest.repos.getReleaseAsset({ | |
| owner, | |
| repo, | |
| asset_id: asset.id, | |
| headers: { | |
| accept: 'application/octet-stream' | |
| } | |
| }); | |
| fs.writeFileSync( | |
| path.join('artifacts', asset.name), | |
| Buffer.from(response.data) | |
| ); | |
| } | |
| } | |
| - name: Generate signatures and updater JSON | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} | |
| TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} | |
| TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Sign artifacts and collect signatures | |
| declare -A signatures | |
| # Sign each artifact and extract signature from output | |
| if [ -f "artifacts/litepost_x64.app.tar.gz" ]; then | |
| signatures["darwin-x86_64"]=$(pnpm tauri signer sign --password "$TAURI_KEY_PASSWORD" "artifacts/litepost_x64.app.tar.gz" | awk -F': ' '/Public signature/{print $2}') | |
| fi | |
| if [ -f "artifacts/litepost_aarch64.app.tar.gz" ]; then | |
| signatures["darwin-aarch64"]=$(pnpm tauri signer sign --password "$TAURI_KEY_PASSWORD" "artifacts/litepost_aarch64.app.tar.gz" | awk -F': ' '/Public signature/{print $2}') | |
| fi | |
| if [ -f "artifacts/litepost_0.1.0_amd64.AppImage" ]; then | |
| signatures["linux-x86_64"]=$(pnpm tauri signer sign --password "$TAURI_KEY_PASSWORD" "artifacts/litepost_0.1.0_amd64.AppImage" | awk -F': ' '/Public signature/{print $2}') | |
| fi | |
| if [ -f "artifacts/litepost_0.1.0_x64-setup.exe" ]; then | |
| signatures["windows-x86_64"]=$(pnpm tauri signer sign --password "$TAURI_KEY_PASSWORD" "artifacts/litepost_0.1.0_x64-setup.exe" | awk -F': ' '/Public signature/{print $2}') | |
| fi | |
| # Create latest.json with collected signatures | |
| echo '{ | |
| "version": "${{ inputs.tag }}", | |
| "notes": "See the assets to download this version and install.", | |
| "pub_date": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'", | |
| "platforms": { | |
| "darwin-x86_64": { | |
| "signature": "'${signatures["darwin-x86_64"]}'", | |
| "url": "https://github.com/LykosAI/LitePost/releases/download/${{ inputs.tag }}/litepost_x64.app.tar.gz" | |
| }, | |
| "darwin-aarch64": { | |
| "signature": "'${signatures["darwin-aarch64"]}'", | |
| "url": "https://github.com/LykosAI/LitePost/releases/download/${{ inputs.tag }}/litepost_aarch64.app.tar.gz" | |
| }, | |
| "linux-x86_64": { | |
| "signature": "'${signatures["linux-x86_64"]}'", | |
| "url": "https://github.com/LykosAI/LitePost/releases/download/${{ inputs.tag }}/litepost_0.1.0_amd64.AppImage" | |
| }, | |
| "windows-x86_64": { | |
| "signature": "'${signatures["windows-x86_64"]}'", | |
| "url": "https://github.com/LykosAI/LitePost/releases/download/${{ inputs.tag }}/litepost_0.1.0_x64-setup.exe" | |
| } | |
| } | |
| }' > latest.json | |
| - name: Upload latest.json | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const tag = '${{ inputs.tag }}'; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Get all releases including drafts | |
| const releases = await github.rest.repos.listReleases({ | |
| owner, | |
| repo, | |
| per_page: 100 | |
| }); | |
| // Find the release by tag, including drafts | |
| const release = releases.data.find(r => r.tag_name === tag); | |
| if (!release) { | |
| throw new Error('Release not found'); | |
| } | |
| // Delete existing latest.json if it exists | |
| for (const asset of release.assets) { | |
| if (asset.name === 'latest.json') { | |
| await github.rest.repos.deleteReleaseAsset({ | |
| owner, | |
| repo, | |
| asset_id: asset.id | |
| }); | |
| break; | |
| } | |
| } | |
| // Upload new latest.json | |
| const contentType = 'application/json'; | |
| const content = await fs.promises.readFile('latest.json'); | |
| await github.rest.repos.uploadReleaseAsset({ | |
| owner, | |
| repo, | |
| release_id: release.id, | |
| name: 'latest.json', | |
| data: content, | |
| headers: { | |
| 'content-type': contentType, | |
| 'content-length': content.length | |
| } | |
| }); |