Skip to content

Release

Release #10

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 1.3.1)'
required: true
type: string
# Grant GITHUB_TOKEN the permissions required to make releases
permissions:
contents: write
jobs:
build-and-release:
runs-on: macos-15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 'latest-stable'
- name: Check Swift version
run: |
swift --version
echo "Xcode version:"
xcodebuild -version
- name: Get version
id: get_version
run: |
if [ "${{ github.event.inputs.version }}" != "" ]; then
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
echo "TAG=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
- name: Update version in code
run: |
VERSION="${{ steps.get_version.outputs.VERSION }}"
sed -i '' "s/static let current: String = \".*\"/static let current: String = \"$VERSION\"/" Sources/CiteBar/AppVersion.swift
BUILD_NUMBER=$(date +%s)
sed -i '' "s/static let build: String = \".*\"/static let build: String = \"$BUILD_NUMBER\"/" Sources/CiteBar/AppVersion.swift
- name: Calculate DMG name (same as Makefile)
id: dmg_name
run: |
# Extract version from AppVersion.swift (same as Makefile)
VERSION=$(grep 'static let current' Sources/CiteBar/AppVersion.swift | cut -d'"' -f2)
# Get architecture and date for DMG naming (match Makefile format exactly)
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
ARCH_NAME="intel"
elif [ "$ARCH" = "arm64" ]; then
ARCH_NAME="arm64"
else
ARCH_NAME="$ARCH"
fi
BUILD_DATE=$(date +%Y%m%d)
DMG_NAME="CiteBar-${VERSION}-${ARCH_NAME}-${BUILD_DATE}"
echo "VERSION_FROM_FILE=$VERSION" >> $GITHUB_OUTPUT
echo "ARCH_NAME=$ARCH_NAME" >> $GITHUB_OUTPUT
echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_OUTPUT
echo "DMG_NAME=$DMG_NAME" >> $GITHUB_OUTPUT
echo "Calculated DMG name: $DMG_NAME"
echo "Version from file: $VERSION"
- name: Build and Package
run: |
# Verify version was updated correctly
UPDATED_VERSION=$(grep 'static let current' Sources/CiteBar/AppVersion.swift | cut -d'"' -f2)
echo "Updated version in code: $UPDATED_VERSION"
echo "Expected version: ${{ steps.get_version.outputs.VERSION }}"
echo "DMG name will be: ${{ steps.dmg_name.outputs.DMG_NAME }}"
# Create properly configured app bundle with Sparkle framework, rpath fixes, and signing
make package
- name: Create DMG
run: |
# Use Makefile to create DMG (it will handle everything properly)
make dmg
# Get the actual DMG file created by Makefile
MAKEFILE_DMG=$(ls dist/*.dmg | head -1)
EXPECTED_DMG="dist/${{ steps.dmg_name.outputs.DMG_NAME }}.dmg"
echo "Makefile created: $MAKEFILE_DMG"
echo "Expected filename: $EXPECTED_DMG"
if [ "$MAKEFILE_DMG" != "$EXPECTED_DMG" ]; then
mv "$MAKEFILE_DMG" "$EXPECTED_DMG"
echo "Renamed DMG: $MAKEFILE_DMG -> $EXPECTED_DMG"
else
echo "DMG filename is already correct"
fi
# Verify the final DMG exists
if [ ! -f "$EXPECTED_DMG" ]; then
echo "Error: Expected DMG file not found: $EXPECTED_DMG"
echo "Available files in dist/:"
ls -la dist/
exit 1
fi
- name: Generate Appcast
run: |
# Get file size and calculate SHA256
DMG_FILE="dist/${{ steps.dmg_name.outputs.DMG_NAME }}.dmg"
DMG_SIZE=$(stat -f%z "$DMG_FILE")
DMG_SHA256=$(shasum -a 256 "$DMG_FILE" | cut -d' ' -f1)
CURRENT_DATE=$(date -u +"%a, %d %b %Y %H:%M:%S %Z")
# Generate release notes from AppVersion.swift
RELEASE_NOTES_HTML=$(swift scripts/extract-release-notes.swift html)
# Create appcast.xml
cat > appcast.xml << EOF
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>CiteBar</title>
<description>Citation Tracking for Academics</description>
<language>en</language>
<link>https://github.com/hichipli/CiteBar</link>
<item>
<title>Version ${{ steps.dmg_name.outputs.VERSION_FROM_FILE }}</title>
<pubDate>$CURRENT_DATE</pubDate>
<description><![CDATA[
$RELEASE_NOTES_HTML
]]></description>
<enclosure url="https://github.com/hichipli/CiteBar/releases/download/${{ steps.get_version.outputs.TAG }}/${{ steps.dmg_name.outputs.DMG_NAME }}.dmg"
sparkle:version="${{ steps.dmg_name.outputs.VERSION_FROM_FILE }}"
sparkle:shortVersionString="${{ steps.dmg_name.outputs.VERSION_FROM_FILE }}"
sparkle:sha256Sum="$DMG_SHA256"
length="$DMG_SIZE"
type="application/octet-stream" />
<sparkle:minimumSystemVersion>13.0</sparkle:minimumSystemVersion>
</item>
</channel>
</rss>
EOF
- name: Create Release
run: |
# Generate release notes from AppVersion.swift
RELEASE_NOTES_MARKDOWN=$(swift scripts/extract-release-notes.swift markdown)
echo "$RELEASE_NOTES_MARKDOWN" > release-notes.md
- name: Publish Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.get_version.outputs.TAG }}
name: CiteBar ${{ steps.dmg_name.outputs.VERSION_FROM_FILE }}
body_path: release-notes.md
draft: false
prerelease: false
files: |
dist/${{ steps.dmg_name.outputs.DMG_NAME }}.dmg
appcast.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}