v0.41.4-alpha #71
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
| # 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; } |