@@ -191,3 +191,146 @@ jobs:
191191 git commit -m "chore(release): publish updater manifest for v${{ steps.get_version.outputs.VERSION }} [skip ci]"
192192 git push origin HEAD:main
193193 fi
194+
195+ build-linux :
196+ needs : build-macos-apple-silicon
197+ runs-on : ubuntu-22.04
198+
199+ steps :
200+ - name : Checkout repository
201+ uses : actions/checkout@v4
202+ with :
203+ token : ${{ secrets.RELEASE_TOKEN }}
204+ fetch-depth : 0
205+ ref : main
206+
207+ - name : Setup Node.js
208+ uses : actions/setup-node@v4
209+ with :
210+ node-version : ' 20'
211+
212+ - name : Setup Rust
213+ uses : dtolnay/rust-toolchain@stable
214+
215+ - name : Cache Rust dependencies
216+ uses : Swatinem/rust-cache@v2
217+ with :
218+ workspaces : src-tauri -> target
219+
220+ - name : Install Tauri Linux dependencies
221+ run : |
222+ sudo apt-get update
223+ sudo apt-get install -y \
224+ libwebkit2gtk-4.1-dev \
225+ build-essential \
226+ curl \
227+ wget \
228+ file \
229+ libxdo-dev \
230+ libssl-dev \
231+ libayatana-appindicator3-dev \
232+ librsvg2-dev \
233+ patchelf
234+
235+ - name : Install dependencies
236+ run : npm install
237+
238+ - name : Get version from package.json
239+ id : get_version
240+ run : |
241+ VERSION=$(node -p "require('./package.json').version")
242+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
243+
244+ - name : Sync Tauri bundle version
245+ run : |
246+ VERSION="${{ steps.get_version.outputs.VERSION }}"
247+ node -e "
248+ const fs = require('fs');
249+ const p = 'src-tauri/tauri.conf.json';
250+ const c = JSON.parse(fs.readFileSync(p, 'utf8'));
251+ c.version = '$VERSION';
252+ fs.writeFileSync(p, JSON.stringify(c, null, 2) + '\n');
253+ "
254+
255+ - name : Build Tauri app
256+ env :
257+ TAURI_SIGNING_PRIVATE_KEY : ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
258+ TAURI_SIGNING_PRIVATE_KEY_PASSWORD : ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
259+ run : npm run tauri build
260+
261+ - name : Collect artifacts
262+ id : artifacts
263+ run : |
264+ VERSION="${{ steps.get_version.outputs.VERSION }}"
265+ DEB_DIR=src-tauri/target/release/bundle/deb
266+ APPIMAGE_DIR=src-tauri/target/release/bundle/appimage
267+
268+ # Rename .deb for release
269+ cd "$DEB_DIR"
270+ SRC_DEB=$(ls *.deb | head -n1)
271+ mv "$SRC_DEB" "AgentGuard-Linux-x86_64.deb"
272+ cd - > /dev/null
273+
274+ # Find the signed AppImage and its .sig
275+ APPIMAGE=$(ls "$APPIMAGE_DIR"/*.AppImage | head -n1)
276+ SIG="${APPIMAGE}.sig"
277+
278+ if [ ! -f "$APPIMAGE" ] || [ ! -f "$SIG" ]; then
279+ echo "ERROR: AppImage updater artifacts missing" >&2
280+ ls -la "$APPIMAGE_DIR" >&2
281+ exit 1
282+ fi
283+
284+ RELEASE_APPIMAGE="AgentGuard_${VERSION}_x86_64.AppImage"
285+ cp "$APPIMAGE" "$APPIMAGE_DIR/$RELEASE_APPIMAGE"
286+ cp "$SIG" "$APPIMAGE_DIR/${RELEASE_APPIMAGE}.sig"
287+
288+ SIG_CONTENT=$(cat "$SIG")
289+ {
290+ echo "SIGNATURE<<SIG_EOF"
291+ echo "$SIG_CONTENT"
292+ echo "SIG_EOF"
293+ } >> $GITHUB_OUTPUT
294+ echo "APPIMAGE_NAME=$RELEASE_APPIMAGE" >> $GITHUB_OUTPUT
295+
296+ - name : Upload Linux artifacts to release
297+ uses : softprops/action-gh-release@v2
298+ with :
299+ tag_name : v${{ steps.get_version.outputs.VERSION }}
300+ files : |
301+ src-tauri/target/release/bundle/deb/AgentGuard-Linux-x86_64.deb
302+ src-tauri/target/release/bundle/appimage/AgentGuard_${{ steps.get_version.outputs.VERSION }}_x86_64.AppImage
303+ src-tauri/target/release/bundle/appimage/AgentGuard_${{ steps.get_version.outputs.VERSION }}_x86_64.AppImage.sig
304+ env :
305+ GITHUB_TOKEN : ${{ secrets.RELEASE_TOKEN }}
306+
307+ - name : Append linux-x86_64 to updater manifest
308+ env :
309+ VERSION : ${{ steps.get_version.outputs.VERSION }}
310+ SIGNATURE : ${{ steps.artifacts.outputs.SIGNATURE }}
311+ APPIMAGE_NAME : ${{ steps.artifacts.outputs.APPIMAGE_NAME }}
312+ run : |
313+ git pull --rebase origin main
314+ node -e "
315+ const fs = require('fs');
316+ const version = process.env.VERSION;
317+ const signature = process.env.SIGNATURE;
318+ const appimage = process.env.APPIMAGE_NAME;
319+ const url = \`https://github.com/\${process.env.GITHUB_REPOSITORY}/releases/download/v\${version}/\${appimage}\`;
320+ const path = 'docs/latest-version.json';
321+ const manifest = JSON.parse(fs.readFileSync(path, 'utf8'));
322+ manifest.platforms['linux-x86_64'] = { signature, url };
323+ fs.writeFileSync(path, JSON.stringify(manifest, null, 2) + '\n');
324+ "
325+
326+ - name : Commit manifest back to main
327+ run : |
328+ git config user.name "github-actions[bot]"
329+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
330+ git add docs/latest-version.json
331+ if git diff --cached --quiet; then
332+ echo "No manifest changes to commit."
333+ else
334+ git commit -m "chore(release): add linux-x86_64 to updater manifest for v${{ steps.get_version.outputs.VERSION }} [skip ci]"
335+ git push origin HEAD:main
336+ fi
0 commit comments