Skip to content

Publish Release

Publish Release #18

Workflow file for this run

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[@]}"