fix(gui): keep system tray alive when GUI window is closed #7
Workflow file for this run
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: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| jobs: | |
| # ── Stage 1: Test & Build Validation ────────────────────────────── | |
| validate: | |
| name: Test & Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| - name: Download dependencies | |
| run: go mod download | |
| - name: Vet | |
| run: go vet ./... | |
| - name: Test | |
| run: go test ./... -v -race | |
| - name: Build (sanity check) | |
| run: go build -o /dev/null ./cmd/routatic-proxy | |
| # ── Stage 2: Create Release ────────────────────────────────────── | |
| release: | |
| name: Create Release | |
| needs: validate | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ steps.version.outputs.tag }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Determine version | |
| id: version | |
| run: | | |
| # Check if there's a tag on this commit | |
| EXACT_TAG=$(git describe --tags --exact-match 2>/dev/null || echo "") | |
| if [ -n "$EXACT_TAG" ]; then | |
| TAG="$EXACT_TAG" | |
| else | |
| # Auto-increment with rollover (0-9 per segment) | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| BASE=${LATEST_TAG#v} | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE" | |
| PATCH=$((PATCH + 1)) | |
| if [ "$PATCH" -gt 9 ]; then | |
| PATCH=0 | |
| MINOR=$((MINOR + 1)) | |
| if [ "$MINOR" -gt 9 ]; then | |
| MINOR=0 | |
| MAJOR=$((MAJOR + 1)) | |
| fi | |
| fi | |
| TAG="v${MAJOR}.${MINOR}.${PATCH}" | |
| fi | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=${TAG#v}" >> "$GITHUB_OUTPUT" | |
| echo "Releasing as $TAG" | |
| - name: Generate AI Changelog | |
| id: changelog | |
| env: | |
| OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} | |
| OPENROUTER_MODEL: ${{ secrets.OPENROUTER_MODEL }} | |
| OPENROUTER_TEMPERATURE: ${{ secrets.OPENROUTER_TEMPERATURE }} | |
| OPENROUTER_MAX_TOKENS: ${{ secrets.OPENROUTER_MAX_TOKENS }} | |
| run: | | |
| sudo apt-get update -qq && sudo apt-get install -y -qq jq curl | |
| # Configuration with defaults | |
| MODEL="${OPENROUTER_MODEL:-openai/gpt-4o-mini}" | |
| TEMP="${OPENROUTER_TEMPERATURE:-0.3}" | |
| TOKENS="${OPENROUTER_MAX_TOKENS:-2000}" | |
| echo "Using OpenRouter model: $MODEL" | |
| # Generate changelog for commits since previous tag | |
| PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") | |
| if [ -n "$PREVIOUS_TAG" ]; then | |
| echo "Generating AI changelog from $PREVIOUS_TAG to ${{ steps.version.outputs.tag }}" | |
| COMMITS=$(git log "${PREVIOUS_TAG}..HEAD" --pretty=format:"%H%n%s%n%b%n---COMMIT_SEP---") | |
| FILE_CHANGES=$(git diff --stat "${PREVIOUS_TAG}..HEAD") | |
| PROMPT="You are a technical writer generating release notes for a Go proxy server project (routatic-proxy). | |
| Analyze the provided git commits and file changes, then generate a well-structured | |
| changelog in Markdown format. Follow these guidelines: | |
| 1. Start with a brief summary paragraph (2-3 sentences) describing the overall theme of this release | |
| 2. Group changes into sections with these exact headers: | |
| - **New Features** - New capabilities, enhancements, additions | |
| - **Bug Fixes** - Fixes for reported or discovered issues | |
| - **Improvements** - Performance, reliability, or code quality improvements | |
| - **Documentation** - README, docs, comments, config updates | |
| - **Chores** - Build, CI/CD, dependency updates, refactoring | |
| 3. Each bullet should be concise but descriptive (one line) | |
| 4. Mention breaking changes prominently with a warning emoji Breaking Changes section at the top | |
| 5. Use present tense, imperative mood (e.g., Add feature not Added feature) | |
| 6. Keep it technical but accessible - target audience is developers using this tool | |
| Format output as clean Markdown without any preamble or explanation. Do not wrap the entire response in a code block." | |
| USER_CONTENT="Git commits since ${PREVIOUS_TAG}:\n\n${COMMITS}\n\nFiles changed:\n\n${FILE_CHANGES}" | |
| # Truncate if too long (~4 chars per token) | |
| MAX_CHARS=12000 | |
| if [ "${#USER_CONTENT}" -gt "$MAX_CHARS" ]; then | |
| USER_CONTENT="${USER_CONTENT:0:MAX_CHARS}\n\n[...truncated for length...]" | |
| fi | |
| RESPONSE=$(curl -s -L -X POST "https://openrouter.ai/api/v1/chat/completions" \ | |
| -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$(jq -n \ | |
| --arg prompt "$PROMPT" \ | |
| --arg user "$USER_CONTENT" \ | |
| --arg model "$MODEL" \ | |
| --arg temp "$TEMP" \ | |
| --arg tokens "$TOKENS" \ | |
| '{ | |
| model: $model, | |
| messages: [ | |
| {role: "system", content: $prompt}, | |
| {role: "user", content: $user} | |
| ], | |
| temperature: ($temp | tonumber), | |
| max_tokens: ($tokens | tonumber) | |
| }' \ | |
| )" \ | |
| ) | |
| CHANGELOG=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty') | |
| if [ -z "$CHANGELOG" ] || [ "$CHANGELOG" = "null" ]; then | |
| echo "Warning: AI changelog generation failed, using commit list instead" >&2 | |
| echo "API response: $RESPONSE" >&2 | |
| CHANGELOG="## Commits\n\n$(git log "${PREVIOUS_TAG}..HEAD" --pretty=format:'- %s')" | |
| fi | |
| else | |
| echo "No previous tag found, using commit list" | |
| CHANGELOG="## Commits\n\n$(git log --pretty=format:'- %s' -20)" | |
| fi | |
| echo "$CHANGELOG" > changelog.md | |
| cat changelog.md | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.tag }} | |
| name: Release ${{ steps.version.outputs.tag }} | |
| body_path: changelog.md | |
| draft: false | |
| prerelease: false | |
| make_latest: true | |
| # ── Stage 2.5: Build macOS DMG ────────────────────────────────── | |
| release-macos: | |
| name: Build & Release macOS DMG | |
| needs: release | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.25" | |
| cache: true | |
| - name: Install create-dmg | |
| run: brew install create-dmg | |
| - name: Build macOS DMG | |
| env: | |
| VERSION: ${{ needs.release.outputs.tag }} | |
| run: | | |
| make dmg VERSION=${{ env.VERSION }} | |
| - name: Upload DMG to Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.release.outputs.tag }} | |
| files: bin/RoutaticProxy.dmg | |
| make_latest: true |