Skip to content

release v0.8.5-rc.1: optimize chat response ui #105

release v0.8.5-rc.1: optimize chat response ui

release v0.8.5-rc.1: optimize chat response ui #105

Workflow file for this run

name: Publish
on:
push:
tags:
- 'v*'
permissions:
contents: write
packages: write
jobs:
publish-npm:
runs-on: ubuntu-latest
outputs:
is_prerelease: ${{ steps.meta.outputs.is_prerelease }}
version: ${{ steps.meta.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Determine release metadata
id: meta
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if [[ "$VERSION" == *"-"* ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
echo "npm_tag=next" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
echo "npm_tag=latest" >> "$GITHUB_OUTPUT"
fi
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
registry-url: 'https://registry.npmjs.org'
- run: pnpm install --frozen-lockfile
- name: Build all packages
run: pnpm build
- name: Build Web UI
run: pnpm --filter @markus/web-ui build
- name: Bundle CLI for publishing
run: pnpm --filter @markus-global/cli build:bundle
- name: Verify bundle
run: |
ls -lh packages/cli/dist/markus.mjs
ls -d packages/cli/dist/web-ui || echo "Warning: Web UI not bundled"
ls -d packages/cli/templates || echo "Warning: templates not bundled"
- name: Publish to npm
run: cd packages/cli && npm publish --access public --tag ${{ steps.meta.outputs.npm_tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
build-server-binary:
needs: publish-npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Build all packages
run: pnpm build
- name: Build Web UI
run: pnpm --filter @markus/web-ui build
- name: Bundle CLI for publishing
run: pnpm --filter @markus-global/cli build:bundle
- name: Build binary archive
run: bash scripts/build-binary.sh linux x64
- name: Upload versioned installer
uses: actions/upload-artifact@v4
with:
name: markus-linux-x64
path: |
dist-binary/markus-v*-linux-x64.*
!dist-binary/markus-v*-linux-x64/
retention-days: 5
- name: Upload fixed-name installer
uses: actions/upload-artifact@v4
with:
name: markus-setup-linux-x64
path: dist-binary/markus-setup-linux-x64.*
retention-days: 5
build-desktop:
needs: publish-npm
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
platform: darwin
arch: arm64
electron_args: "--mac --arm64"
- os: macos-latest
platform: darwin
arch: x64
electron_args: "--mac --x64"
- os: windows-latest
platform: win
arch: x64
electron_args: "--win --x64"
- os: ubuntu-latest
platform: linux
arch: x64
electron_args: "--linux --x64"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Build all packages
run: pnpm build
- name: Build Web UI
run: pnpm --filter @markus/web-ui build
- name: Build Electron app
run: pnpm --filter @markus/desktop build:electron
- name: Import Apple certificates
if: matrix.platform == 'darwin'
env:
APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
if [ -z "$APPLE_CERTIFICATE_P12" ]; then
echo "⚠ Apple signing secrets not configured — skipping"
exit 0
fi
KEYCHAIN="desktop-$$.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -hex 12)"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
security set-keychain-settings -lut 900 "$KEYCHAIN"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
echo "$APPLE_CERTIFICATE_P12" | base64 --decode > /tmp/cert.p12
security import /tmp/cert.p12 -k "$KEYCHAIN" -P "$APPLE_CERTIFICATE_PASSWORD" \
-T /usr/bin/codesign
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
rm /tmp/cert.p12
echo "DESKTOP_KEYCHAIN=$KEYCHAIN" >> "$GITHUB_ENV"
- name: Package Electron app
working-directory: packages/desktop
run: pnpm dist ${{ matrix.electron_args }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Cleanup Apple keychain
if: always() && matrix.platform == 'darwin' && env.DESKTOP_KEYCHAIN != ''
run: security delete-keychain "$DESKTOP_KEYCHAIN" 2>/dev/null || true
- name: Upload Electron artifacts
uses: actions/upload-artifact@v4
with:
name: markus-desktop-${{ matrix.platform }}-${{ matrix.arch }}
path: |
packages/desktop/dist-electron/*.dmg
packages/desktop/dist-electron/*.exe
packages/desktop/dist-electron/*.AppImage
retention-days: 5
github-release:
runs-on: ubuntu-latest
needs: [publish-npm, build-server-binary, build-desktop]
steps:
- uses: actions/checkout@v4
- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -lhR artifacts/ || echo "No artifacts"
- name: Create GitHub Release (stable)
if: needs.publish-npm.outputs.is_prerelease == 'false'
uses: softprops/action-gh-release@v3
with:
name: v${{ steps.version.outputs.VERSION }}
prerelease: false
generate_release_notes: true
files: artifacts/*
body: |
## Desktop App (recommended)
| Platform | Download |
|----------|----------|
| macOS (Apple Silicon) | [Markus.dmg](https://github.com/markus-global/markus/releases/download/v${{ steps.version.outputs.VERSION }}/Markus-${{ steps.version.outputs.VERSION }}-arm64.dmg) |
| macOS (Intel) | [Markus.dmg](https://github.com/markus-global/markus/releases/download/v${{ steps.version.outputs.VERSION }}/Markus-${{ steps.version.outputs.VERSION }}.dmg) |
| Windows x64 | [Markus-Setup.exe](https://github.com/markus-global/markus/releases/download/v${{ steps.version.outputs.VERSION }}/Markus-Setup-${{ steps.version.outputs.VERSION }}.exe) |
| Linux x64 | [Markus.AppImage](https://github.com/markus-global/markus/releases/download/v${{ steps.version.outputs.VERSION }}/Markus-${{ steps.version.outputs.VERSION }}.AppImage) |
## Server / CLI
```bash
# macOS / Linux (one-liner)
curl -fsSL https://markus.global/install.sh | bash
# npm (requires Node.js 22+)
npm install -g @markus-global/cli@${{ steps.version.outputs.VERSION }}
```
Linux server binary: [markus-setup-linux-x64.deb](https://github.com/markus-global/markus/releases/download/v${{ steps.version.outputs.VERSION }}/markus-setup-linux-x64.deb)
- name: Create GitHub Release (pre-release)
if: needs.publish-npm.outputs.is_prerelease == 'true'
uses: softprops/action-gh-release@v3
with:
name: v${{ steps.version.outputs.VERSION }} (Pre-release)
prerelease: true
generate_release_notes: true
files: artifacts/*
body: |
> **Pre-release** — for testing only. `install.sh` always installs the latest stable.
```bash
npm install -g @markus-global/cli@${{ steps.version.outputs.VERSION }}
```
upload-to-hub:
runs-on: ubuntu-latest
needs: [publish-npm, build-server-binary, build-desktop, github-release]
if: needs.publish-npm.outputs.is_prerelease == 'false'
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Upload to R2
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_ENDPOINT: https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com
R2_BUCKET: ${{ secrets.R2_BUCKET_NAME }}
VERSION: ${{ needs.publish-npm.outputs.version }}
run: |
set -e
uploaded=0
for file in artifacts/markus-setup-* artifacts/markus-v${VERSION}-* artifacts/Markus-*.dmg artifacts/Markus-*.AppImage artifacts/Markus*.exe; do
[ -f "$file" ] || continue
filename=$(basename "$file")
echo "Uploading $filename to R2..."
aws s3 cp "$file" "s3://${R2_BUCKET}/releases/${filename}" \
--endpoint-url "$R2_ENDPOINT" \
--content-type "application/octet-stream"
uploaded=$((uploaded + 1))
done
if [ "$uploaded" -eq 0 ]; then
echo "::error::No artifacts found to upload"
exit 1
fi
echo "{\"version\":\"$VERSION\",\"updatedAt\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > /tmp/meta.json
aws s3 cp /tmp/meta.json "s3://${R2_BUCKET}/releases/meta.json" \
--endpoint-url "$R2_ENDPOINT" \
--content-type "application/json"
echo "Uploaded $uploaded files + meta.json to R2"