Skip to content

v0.41.4-alpha

v0.41.4-alpha #71

# This GitHub Actions workflow is triggered when a GitHub Release is created, builds and uploads desktop applications as .zip files as release assets.
name: Release Desktop Apps
on:
# Trigger on when a new release is published
release:
types: [published]
# Allow manual triggering of the workflow for testing (artifacts will be uploaded to the workflow run, not a release))
workflow_dispatch:
jobs:
build-and-upload:
runs-on: ubuntu-latest
# Skip the entire workflow for vscode-* releases (the GitHub `release`
# trigger has no tag filter, so we gate every job by the same condition
# instead of doing it per-job).
if: ${{ !startsWith(github.event.release.tag_name || github.ref_name, 'vscode-') }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
runtime: [win-x64, win-arm64, linux-x64, linux-arm64, osx-arm64]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
# Stamp the release version (tag without leading "v", e.g. "0.40.2-alpha") into the
# published app assemblies so the in-app update checker can compare against GitHub
# releases. Only set on the `release` trigger; for `workflow_dispatch` it stays empty,
# so publish.sh leaves the default 1.0.0 (treated as "unknown -> skip update check").
- name: Determine release version
if: github.event_name == 'release'
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: echo "RELEASE_VERSION=${TAG_NAME#v}" >> "$GITHUB_ENV"
- name: Publish SilkNetNative App
run: |
chmod u+x src/apps/SilkNetNative/Highbyte.DotNet6502.App.SilkNetNative/publish.sh
src/apps/SilkNetNative/Highbyte.DotNet6502.App.SilkNetNative/publish.sh ${{ matrix.runtime }}
- name: Publish Avalonia Desktop App
run: |
chmod u+x src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Desktop/publish.sh
src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Desktop/publish.sh ${{ matrix.runtime }}
- name: Publish SadConsole App
run: |
chmod u+x src/apps/SadConsole/Highbyte.DotNet6502.App.SadConsole/publish.sh
src/apps/SadConsole/Highbyte.DotNet6502.App.SadConsole/publish.sh ${{ matrix.runtime }}
- name: Publish Headless App
run: |
chmod u+x src/apps/Highbyte.DotNet6502.App.Headless/publish.sh
src/apps/Highbyte.DotNet6502.App.Headless/publish.sh ${{ matrix.runtime }}
- name: Publish RemoteClient App
run: |
chmod u+x src/apps/Highbyte.DotNet6502.App.RemoteClient/publish.sh
src/apps/Highbyte.DotNet6502.App.RemoteClient/publish.sh ${{ matrix.runtime }}
- name: Publish Terminal App
run: |
chmod u+x src/apps/Terminal/Highbyte.DotNet6502.App.Terminal/publish.sh
src/apps/Terminal/Highbyte.DotNet6502.App.Terminal/publish.sh ${{ matrix.runtime }}
- name: Zip Apps
run: |
cd src/apps/SilkNetNative/Highbyte.DotNet6502.App.SilkNetNative/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-SilkNetNative-${{ matrix.runtime }}.zip .
cd $GITHUB_WORKSPACE/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Desktop/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-Avalonia-${{ matrix.runtime }}.zip .
cd $GITHUB_WORKSPACE/src/apps/SadConsole/Highbyte.DotNet6502.App.SadConsole/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-SadConsole-${{ matrix.runtime }}.zip .
cd $GITHUB_WORKSPACE/src/apps/Highbyte.DotNet6502.App.Headless/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-Headless-${{ matrix.runtime }}.zip .
cd $GITHUB_WORKSPACE/src/apps/Highbyte.DotNet6502.App.RemoteClient/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-RemoteClient-${{ matrix.runtime }}.zip .
cd $GITHUB_WORKSPACE/src/apps/Terminal/Highbyte.DotNet6502.App.Terminal/publish/${{ matrix.runtime }}
zip -r $GITHUB_WORKSPACE/DotNet6502-Terminal-${{ matrix.runtime }}.zip .
- name: Generate SHA256 checksums
run: |
cd $GITHUB_WORKSPACE
sha256sum DotNet6502-SilkNetNative-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
sha256sum DotNet6502-Avalonia-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
sha256sum DotNet6502-SadConsole-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
sha256sum DotNet6502-Headless-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
sha256sum DotNet6502-RemoteClient-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
sha256sum DotNet6502-Terminal-${{ matrix.runtime }}.zip >> checksums-${{ matrix.runtime }}.sha256
- name: Upload Release Assets
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
gh release upload "$TAG_NAME" \
DotNet6502-SilkNetNative-${{ matrix.runtime }}.zip \
DotNet6502-Avalonia-${{ matrix.runtime }}.zip \
DotNet6502-SadConsole-${{ matrix.runtime }}.zip \
DotNet6502-Headless-${{ matrix.runtime }}.zip \
DotNet6502-RemoteClient-${{ matrix.runtime }}.zip \
DotNet6502-Terminal-${{ matrix.runtime }}.zip \
checksums-${{ matrix.runtime }}.sha256
- name: Upload Workflow Artifacts (non-release)
if: github.event_name != 'release'
uses: actions/upload-artifact@v4
with:
name: DotNet6502-desktop-apps-${{ matrix.runtime }}
path: |
DotNet6502-SilkNetNative-${{ matrix.runtime }}.zip
DotNet6502-Avalonia-${{ matrix.runtime }}.zip
DotNet6502-SadConsole-${{ matrix.runtime }}.zip
DotNet6502-Headless-${{ matrix.runtime }}.zip
DotNet6502-RemoteClient-${{ matrix.runtime }}.zip
DotNet6502-Terminal-${{ matrix.runtime }}.zip
checksums-${{ matrix.runtime }}.sha256
update-package-managers:
if: ${{ github.event_name == 'release' && !startsWith(github.event.release.tag_name, 'vscode-') }}
needs: build-and-upload
runs-on: ubuntu-latest
steps:
- name: Extract version from tag
id: version
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
TAG="$TAG_NAME"
VERSION="${TAG#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- name: Download checksum files and macOS zip from release
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ github.event.release.tag_name }}
run: |
for runtime in osx-arm64 linux-x64 linux-arm64 win-x64 win-arm64; do
gh release download "$TAG_NAME" \
--repo ${{ github.repository }} \
--pattern "checksums-${runtime}.sha256"
done
gh release download "$TAG_NAME" \
--repo ${{ github.repository }} \
--pattern "DotNet6502-Avalonia-osx-arm64.zip"
- name: Extract SHA256 hashes
id: hashes
run: |
extract_hash() {
grep "DotNet6502-${1}-${2}.zip" "checksums-${2}.sha256" | awk '{print $1}'
}
echo "osx_arm64=$(extract_hash Avalonia osx-arm64)" >> "$GITHUB_OUTPUT"
echo "linux_x64=$(extract_hash Avalonia linux-x64)" >> "$GITHUB_OUTPUT"
echo "linux_arm64=$(extract_hash Avalonia linux-arm64)" >> "$GITHUB_OUTPUT"
echo "win_x64=$(extract_hash Avalonia win-x64)" >> "$GITHUB_OUTPUT"
echo "win_arm64=$(extract_hash Avalonia win-arm64)" >> "$GITHUB_OUTPUT"
echo "headless_osx_arm64=$(extract_hash Headless osx-arm64)" >> "$GITHUB_OUTPUT"
echo "headless_linux_x64=$(extract_hash Headless linux-x64)" >> "$GITHUB_OUTPUT"
echo "headless_linux_arm64=$(extract_hash Headless linux-arm64)" >> "$GITHUB_OUTPUT"
echo "headless_win_x64=$(extract_hash Headless win-x64)" >> "$GITHUB_OUTPUT"
echo "headless_win_arm64=$(extract_hash Headless win-arm64)" >> "$GITHUB_OUTPUT"
echo "remote_osx_arm64=$(extract_hash RemoteClient osx-arm64)" >> "$GITHUB_OUTPUT"
echo "remote_linux_x64=$(extract_hash RemoteClient linux-x64)" >> "$GITHUB_OUTPUT"
echo "remote_linux_arm64=$(extract_hash RemoteClient linux-arm64)" >> "$GITHUB_OUTPUT"
echo "remote_win_x64=$(extract_hash RemoteClient win-x64)" >> "$GITHUB_OUTPUT"
echo "remote_win_arm64=$(extract_hash RemoteClient win-arm64)" >> "$GITHUB_OUTPUT"
echo "terminal_osx_arm64=$(extract_hash Terminal osx-arm64)" >> "$GITHUB_OUTPUT"
echo "terminal_linux_x64=$(extract_hash Terminal linux-x64)" >> "$GITHUB_OUTPUT"
echo "terminal_linux_arm64=$(extract_hash Terminal linux-arm64)" >> "$GITHUB_OUTPUT"
echo "terminal_win_x64=$(extract_hash Terminal win-x64)" >> "$GITHUB_OUTPUT"
echo "terminal_win_arm64=$(extract_hash Terminal win-arm64)" >> "$GITHUB_OUTPUT"
- name: Extract macOS app bundle name from zip
id: app_bundle
run: |
APP_NAME=$(zipinfo -1 DotNet6502-Avalonia-osx-arm64.zip | grep -E '^[^/]+\.app/$' | sed 's|/$||' | head -1)
echo "app_name=$APP_NAME" >> "$GITHUB_OUTPUT"
- name: Update Homebrew tap
env:
GH_TOKEN: ${{ secrets.PACKAGE_MANAGER_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
APP_NAME: ${{ steps.app_bundle.outputs.app_name }}
OSX_ARM64_HASH: ${{ steps.hashes.outputs.osx_arm64 }}
LINUX_X64_HASH: ${{ steps.hashes.outputs.linux_x64 }}
LINUX_ARM64_HASH: ${{ steps.hashes.outputs.linux_arm64 }}
HEADLESS_OSX_ARM64_HASH: ${{ steps.hashes.outputs.headless_osx_arm64 }}
HEADLESS_LINUX_X64_HASH: ${{ steps.hashes.outputs.headless_linux_x64 }}
HEADLESS_LINUX_ARM64_HASH: ${{ steps.hashes.outputs.headless_linux_arm64 }}
REMOTE_OSX_ARM64_HASH: ${{ steps.hashes.outputs.remote_osx_arm64 }}
REMOTE_LINUX_X64_HASH: ${{ steps.hashes.outputs.remote_linux_x64 }}
REMOTE_LINUX_ARM64_HASH: ${{ steps.hashes.outputs.remote_linux_arm64 }}
TERMINAL_OSX_ARM64_HASH: ${{ steps.hashes.outputs.terminal_osx_arm64 }}
TERMINAL_LINUX_X64_HASH: ${{ steps.hashes.outputs.terminal_linux_x64 }}
TERMINAL_LINUX_ARM64_HASH: ${{ steps.hashes.outputs.terminal_linux_arm64 }}
run: |
git clone "https://x-access-token:${GH_TOKEN}@github.com/highbyte/homebrew-dotnet-6502.git"
cd homebrew-dotnet-6502
# Update Cask (macOS desktop app)
sed -i "s/version \".*\"/version \"${VERSION}\"/" Casks/dotnet-6502.rb
sed -i "s/sha256 \".*\"/sha256 \"${OSX_ARM64_HASH}\"/" Casks/dotnet-6502.rb
# Update .app bundle name (read from the actual release zip, not source)
sed -i "s|app \".*\.app\"|app \"${APP_NAME}\"|" Casks/dotnet-6502.rb
sed -i "s|binary \".*\.app/Contents/MacOS/|binary \"${APP_NAME}/Contents/MacOS/|" Casks/dotnet-6502.rb
# Update Formulas - use Python for multi-hash replacement
python3 <<'PYEOF'
import re, os
def update_formula(path, version, hashes):
with open(path, "r") as f:
content = f.read()
content = re.sub(r'version ".*?"', f'version "{version}"', content)
idx = [0]
def replace_hash(m):
if idx[0] < len(hashes):
h = hashes[idx[0]]
idx[0] += 1
return f'sha256 "{h}"'
return m.group(0)
content = re.sub(r'sha256 ".*?"', replace_hash, content)
with open(path, "w") as f:
f.write(content)
version = os.environ["VERSION"]
# dotnet-6502 formula: Linux only (x64, arm64)
update_formula("Formula/dotnet-6502.rb", version, [
os.environ["LINUX_X64_HASH"],
os.environ["LINUX_ARM64_HASH"],
])
# dotnet-6502-headless formula: macOS arm64, then Linux x64, then Linux arm64
update_formula("Formula/dotnet-6502-headless.rb", version, [
os.environ["HEADLESS_OSX_ARM64_HASH"],
os.environ["HEADLESS_LINUX_X64_HASH"],
os.environ["HEADLESS_LINUX_ARM64_HASH"],
])
# dotnet-6502-remote formula: macOS arm64, then Linux x64, then Linux arm64
update_formula("Formula/dotnet-6502-remote.rb", version, [
os.environ["REMOTE_OSX_ARM64_HASH"],
os.environ["REMOTE_LINUX_X64_HASH"],
os.environ["REMOTE_LINUX_ARM64_HASH"],
])
# dotnet-6502-terminal formula: macOS arm64, then Linux x64, then Linux arm64
update_formula("Formula/dotnet-6502-terminal.rb", version, [
os.environ["TERMINAL_OSX_ARM64_HASH"],
os.environ["TERMINAL_LINUX_X64_HASH"],
os.environ["TERMINAL_LINUX_ARM64_HASH"],
])
PYEOF
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --cached --quiet || { git commit -m "Update to ${VERSION}" && git push; }
- name: Update Scoop bucket
env:
GH_TOKEN: ${{ secrets.PACKAGE_MANAGER_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
TAG: ${{ steps.version.outputs.tag }}
WIN_X64_HASH: ${{ steps.hashes.outputs.win_x64 }}
WIN_ARM64_HASH: ${{ steps.hashes.outputs.win_arm64 }}
HEADLESS_WIN_X64_HASH: ${{ steps.hashes.outputs.headless_win_x64 }}
HEADLESS_WIN_ARM64_HASH: ${{ steps.hashes.outputs.headless_win_arm64 }}
REMOTE_WIN_X64_HASH: ${{ steps.hashes.outputs.remote_win_x64 }}
REMOTE_WIN_ARM64_HASH: ${{ steps.hashes.outputs.remote_win_arm64 }}
TERMINAL_WIN_X64_HASH: ${{ steps.hashes.outputs.terminal_win_x64 }}
TERMINAL_WIN_ARM64_HASH: ${{ steps.hashes.outputs.terminal_win_arm64 }}
run: |
git clone "https://x-access-token:${GH_TOKEN}@github.com/highbyte/scoop-dotnet-6502.git"
cd scoop-dotnet-6502
python3 <<'PYEOF'
import json, os
version = os.environ["VERSION"]
tag = os.environ["TAG"]
def update_manifest(path, app_name, win_x64_hash, win_arm64_hash):
with open(path, "r") as f:
manifest = json.load(f)
manifest["version"] = version
manifest["architecture"]["64bit"]["url"] = f"https://github.com/highbyte/dotnet-6502/releases/download/{tag}/DotNet6502-{app_name}-win-x64.zip"
manifest["architecture"]["64bit"]["hash"] = win_x64_hash
manifest["architecture"]["arm64"]["url"] = f"https://github.com/highbyte/dotnet-6502/releases/download/{tag}/DotNet6502-{app_name}-win-arm64.zip"
manifest["architecture"]["arm64"]["hash"] = win_arm64_hash
with open(path, "w") as f:
json.dump(manifest, f, indent=4)
f.write("\n")
update_manifest("bucket/dotnet-6502.json", "Avalonia", os.environ["WIN_X64_HASH"], os.environ["WIN_ARM64_HASH"])
update_manifest("bucket/dotnet-6502-headless.json", "Headless", os.environ["HEADLESS_WIN_X64_HASH"], os.environ["HEADLESS_WIN_ARM64_HASH"])
update_manifest("bucket/dotnet-6502-remote.json", "RemoteClient", os.environ["REMOTE_WIN_X64_HASH"], os.environ["REMOTE_WIN_ARM64_HASH"])
update_manifest("bucket/dotnet-6502-terminal.json", "Terminal", os.environ["TERMINAL_WIN_X64_HASH"], os.environ["TERMINAL_WIN_ARM64_HASH"])
PYEOF
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --cached --quiet || { git commit -m "Update to ${VERSION}" && git push; }