Publish Release #18
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: Publish Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| run_id: | |
| description: "Build run ID to release (leave blank to use the latest successful build)" | |
| required: false | |
| type: string | |
| version: | |
| description: "Version tag (e.g. v1.2.3) — leave blank to use package.json version" | |
| required: false | |
| type: string | |
| prerelease: | |
| description: "Mark as pre-release" | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| actions: read | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| actions: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Resolve build run ID | |
| id: run | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| if [ -n "${{ inputs.run_id }}" ]; then | |
| RUN_ID="${{ inputs.run_id }}" | |
| else | |
| RUN_ID=$(gh api \ | |
| "repos/${{ github.repository }}/actions/workflows/build.yml/runs?branch=main&status=success&per_page=1" \ | |
| --jq '.workflow_runs[0].id') | |
| fi | |
| echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT | |
| echo "Using build run ID: $RUN_ID" | |
| - name: Resolve version tag | |
| id: version | |
| run: | | |
| if [ -n "${{ inputs.version }}" ]; then | |
| TAG="${{ inputs.version }}" | |
| [[ "$TAG" == v* ]] || TAG="v$TAG" | |
| else | |
| TAG="v$(node -p "require('./package.json').version")" | |
| fi | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "Resolved release tag: $TAG" | |
| - name: Create and push tag | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}" | |
| git push origin "${{ steps.version.outputs.tag }}" | |
| - name: Download artifacts from build run | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| pattern: installers-* | |
| run-id: ${{ steps.run.outputs.run_id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate release notes | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PREV_TAG=$(git tag --sort=-version:refname \ | |
| | grep -v "^${{ steps.version.outputs.tag }}$" \ | |
| | grep -E '^v[0-9]' \ | |
| | head -1 || true) | |
| if [ -n "$PREV_TAG" ]; then | |
| GENERATED=$(gh api repos/${{ github.repository }}/releases/generate-notes \ | |
| -f tag_name="${{ steps.version.outputs.tag }}" \ | |
| -f target_commitish="main" \ | |
| -f previous_tag_name="$PREV_TAG" \ | |
| --jq '.body') | |
| else | |
| GENERATED=$(gh api repos/${{ github.repository }}/releases/generate-notes \ | |
| -f tag_name="${{ steps.version.outputs.tag }}" \ | |
| -f target_commitish="main" \ | |
| --jq '.body') | |
| fi | |
| # Build downloads table from artifacts that actually exist | |
| HAS_MAC=$(find artifacts -name "*.dmg" 2>/dev/null | head -1) | |
| HAS_WIN=$(find artifacts \( -name "*.msi" -o -name "*.exe" \) 2>/dev/null | head -1) | |
| HAS_LINUX=$(find artifacts \( -name "*.deb" -o -name "*.AppImage" \) 2>/dev/null | head -1) | |
| DOWNLOADS_TABLE="| Platform | File |\n|----------|------|" | |
| [ -n "$HAS_MAC" ] && DOWNLOADS_TABLE="$DOWNLOADS_TABLE\n| macOS | \`.dmg\` |" | |
| [ -n "$HAS_WIN" ] && DOWNLOADS_TABLE="$DOWNLOADS_TABLE\n| Windows | \`.msi\` or \`.exe\` |" | |
| [ -n "$HAS_LINUX" ] && DOWNLOADS_TABLE="$DOWNLOADS_TABLE\n| Linux | \`.deb\` or \`.AppImage\` |" | |
| { | |
| echo "$GENERATED" | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "## Downloads" | |
| echo "" | |
| echo -e "$DOWNLOADS_TABLE" | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "## Installation Notes" | |
| if [ -n "$HAS_MAC" ]; then | |
| echo "" | |
| echo "### macOS" | |
| echo 'Fetch Boy is not yet signed with an Apple Developer certificate. macOS will show a **"damaged and can'"'"'t be opened"** error. The app is not damaged — this is Gatekeeper blocking unsigned apps.' | |
| echo "" | |
| echo "**Run this in Terminal after dragging it to Applications:**" | |
| echo '```bash' | |
| echo 'xattr -cr /Applications/Fetch\ Boy.app' | |
| echo '```' | |
| echo "You only need to do this once." | |
| fi | |
| if [ -n "$HAS_LINUX" ]; then | |
| echo "" | |
| echo "### Linux (AppImage)" | |
| echo "Make the file executable before running:" | |
| echo '```bash' | |
| echo "chmod +x \"Fetch Boy_${{ steps.version.outputs.tag }}_amd64.AppImage\"" | |
| echo '```' | |
| fi | |
| } > release-notes.md | |
| - name: Create public GitHub release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PRERELEASE_FLAG="" | |
| if [ "${{ inputs.prerelease }}" = "true" ]; then | |
| PRERELEASE_FLAG="--prerelease" | |
| fi | |
| mapfile -t FILE_ARRAY < <(find artifacts -type f \( \ | |
| -name "*.dmg" -o -name "*.msi" -o -name "*.exe" \ | |
| -o -name "*.deb" -o -name "*.AppImage" \)) | |
| gh release create "${{ steps.version.outputs.tag }}" \ | |
| --title "Fetch Boy ${{ steps.version.outputs.tag }}" \ | |
| --notes-file release-notes.md \ | |
| $PRERELEASE_FLAG \ | |
| "${FILE_ARRAY[@]}" |