v0.4.36 #40
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
| name: Release Packages | |
| on: | |
| release: | |
| types: [published] | |
| permissions: | |
| contents: write | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Build release binaries for all platforms | |
| # --------------------------------------------------------------------------- | |
| build: | |
| strategy: | |
| matrix: | |
| include: | |
| - os: macos-14 | |
| target: aarch64-apple-darwin | |
| artifact: perry-macos-aarch64 | |
| - os: macos-15 | |
| target: x86_64-apple-darwin | |
| artifact: perry-macos-x86_64 | |
| - os: ubuntu-22.04 | |
| target: x86_64-unknown-linux-gnu | |
| artifact: perry-linux-x86_64 | |
| - os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| artifact: perry-linux-aarch64 | |
| - os: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| artifact: perry-windows-x86_64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install GTK4 development libraries (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y libgtk-4-dev | |
| - name: Build perry | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Build runtime libraries | |
| run: | | |
| cargo build --release --target ${{ matrix.target }} -p perry-runtime | |
| cargo build --release --target ${{ matrix.target }} -p perry-stdlib | |
| - name: Build UI library (macOS) | |
| if: runner.os == 'macOS' | |
| run: cargo build --release --target ${{ matrix.target }} -p perry-ui-macos | |
| - name: Build UI library (Linux) | |
| if: runner.os == 'Linux' | |
| run: cargo build --release --target ${{ matrix.target }} -p perry-ui-gtk4 | |
| - name: Build UI library (Windows) | |
| if: runner.os == 'Windows' | |
| run: cargo build --release --target ${{ matrix.target }} -p perry-ui-windows | |
| - name: Package release archive (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| mkdir -p staging | |
| cp target/${{ matrix.target }}/release/perry staging/ | |
| # Include static libraries for linking (runtime, stdlib, UI) | |
| for lib in libperry_runtime.a libperry_stdlib.a libperry_ui_macos.a libperry_ui_gtk4.a; do | |
| if [ -f "target/${{ matrix.target }}/release/$lib" ]; then | |
| cp "target/${{ matrix.target }}/release/$lib" staging/ | |
| fi | |
| done | |
| cd staging | |
| tar czf ../${{ matrix.artifact }}.tar.gz * | |
| - name: Package release archive (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force -Path staging | |
| Copy-Item "target/${{ matrix.target }}/release/perry.exe" staging/ | |
| # Include static libraries for linking (runtime, stdlib, UI) | |
| $libs = @("perry_runtime.lib", "perry_stdlib.lib", "perry_ui_windows.lib") | |
| foreach ($lib in $libs) { | |
| $path = "target/${{ matrix.target }}/release/$lib" | |
| if (Test-Path $path) { | |
| Copy-Item $path staging/ | |
| } | |
| } | |
| Compress-Archive -Path staging/* -DestinationPath "${{ matrix.artifact }}.zip" | |
| - name: Upload release asset (Unix) | |
| if: runner.os != 'Windows' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh release upload "${{ github.event.release.tag_name }}" "${{ matrix.artifact }}.tar.gz" --clobber | |
| - name: Upload release asset (Windows) | |
| if: runner.os == 'Windows' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: gh release upload "${{ github.event.release.tag_name }}" "${{ matrix.artifact }}.zip" --clobber | |
| - name: Upload build artifact (for deb job) | |
| if: runner.os != 'Windows' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: staging/ | |
| # --------------------------------------------------------------------------- | |
| # Update Homebrew tap | |
| # --------------------------------------------------------------------------- | |
| homebrew: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get release info | |
| id: release | |
| run: | | |
| TAG="${{ github.event.release.tag_name }}" | |
| VERSION="${TAG#v}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${TAG}" >> "$GITHUB_OUTPUT" | |
| - name: Download source tarball and compute SHA256 | |
| id: sha | |
| run: | | |
| curl -sL "https://github.com/${{ github.repository }}/archive/refs/tags/${{ steps.release.outputs.tag }}.tar.gz" -o source.tar.gz | |
| SHA256=$(sha256sum source.tar.gz | cut -d' ' -f1) | |
| echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" | |
| - name: Download macOS ARM64 bottle and compute SHA256 | |
| id: bottle_arm64 | |
| run: | | |
| curl -sL "https://github.com/${{ github.repository }}/releases/download/${{ steps.release.outputs.tag }}/perry-macos-aarch64.tar.gz" -o perry-macos-aarch64.tar.gz | |
| SHA256=$(sha256sum perry-macos-aarch64.tar.gz | cut -d' ' -f1) | |
| echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" | |
| - name: Download macOS x86_64 bottle and compute SHA256 | |
| id: bottle_x64 | |
| run: | | |
| curl -sL "https://github.com/${{ github.repository }}/releases/download/${{ steps.release.outputs.tag }}/perry-macos-x86_64.tar.gz" -o perry-macos-x86_64.tar.gz | |
| SHA256=$(sha256sum perry-macos-x86_64.tar.gz | cut -d' ' -f1) | |
| echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" | |
| - name: Update Homebrew tap | |
| env: | |
| TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| run: | | |
| git clone "https://x-access-token:${TAP_TOKEN}@github.com/PerryTS/homebrew-perry.git" tap | |
| cd tap | |
| mkdir -p Formula | |
| cat > Formula/perry.rb << 'FORMULA_EOF' | |
| class Perry < Formula | |
| desc "Native TypeScript compiler — compiles TypeScript to native executables" | |
| homepage "https://github.com/PerryTS/perry" | |
| version "${{ steps.release.outputs.version }}" | |
| license "MIT" | |
| on_macos do | |
| if Hardware::CPU.arm? | |
| url "https://github.com/PerryTS/perry/releases/download/${{ steps.release.outputs.tag }}/perry-macos-aarch64.tar.gz" | |
| sha256 "${{ steps.bottle_arm64.outputs.sha256 }}" | |
| else | |
| url "https://github.com/PerryTS/perry/releases/download/${{ steps.release.outputs.tag }}/perry-macos-x86_64.tar.gz" | |
| sha256 "${{ steps.bottle_x64.outputs.sha256 }}" | |
| end | |
| end | |
| on_linux do | |
| url "https://github.com/PerryTS/perry/archive/refs/tags/${{ steps.release.outputs.tag }}.tar.gz" | |
| sha256 "${{ steps.sha.outputs.sha256 }}" | |
| depends_on "rust" => :build | |
| end | |
| def install | |
| if OS.mac? | |
| bin.install "perry" | |
| lib.install Dir["libperry_*.a"] | |
| else | |
| system "cargo", "build", "--release" | |
| system "cargo", "build", "--release", "-p", "perry-runtime", "-p", "perry-stdlib" | |
| bin.install "target/release/perry" | |
| lib.install Dir["target/release/libperry_*.a"] | |
| end | |
| end | |
| def caveats | |
| <<~EOS | |
| Perry requires a C linker to link compiled executables. | |
| macOS: Xcode Command Line Tools (xcode-select --install) | |
| Linux: GCC or Clang (sudo apt install build-essential) | |
| Quick start: | |
| echo 'console.log("hello")' > hello.ts | |
| perry hello.ts -o hello && ./hello | |
| EOS | |
| end | |
| test do | |
| assert_match "perry", shell_output("#{bin}/perry --version") | |
| (testpath/"test.ts").write('console.log("works");') | |
| system bin/"perry", testpath/"test.ts", "-o", testpath/"test" | |
| assert_equal "works\n", shell_output(testpath/"test") | |
| end | |
| end | |
| FORMULA_EOF | |
| # Remove leading whitespace from heredoc indentation | |
| sed -i 's/^ //' Formula/perry.rb | |
| git config user.name "perry-bot" | |
| git config user.email "bot@perryts.com" | |
| git add Formula/perry.rb | |
| git commit -m "perry ${VERSION}" || echo "No changes" | |
| git push | |
| # --------------------------------------------------------------------------- | |
| # Build .deb packages and update APT repository | |
| # --------------------------------------------------------------------------- | |
| apt: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - artifact: perry-linux-x86_64 | |
| arch: amd64 | |
| - artifact: perry-linux-aarch64 | |
| arch: arm64 | |
| steps: | |
| - name: Get release info | |
| id: release | |
| run: | | |
| TAG="${{ github.event.release.tag_name }}" | |
| VERSION="${TAG#v}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: staging/ | |
| - name: Build .deb package | |
| run: | | |
| VERSION="${{ steps.release.outputs.version }}" | |
| ARCH="${{ matrix.arch }}" | |
| PKG="perry_${VERSION}_${ARCH}" | |
| mkdir -p "${PKG}/DEBIAN" | |
| mkdir -p "${PKG}/usr/bin" | |
| mkdir -p "${PKG}/usr/lib/perry" | |
| cat > "${PKG}/DEBIAN/control" << EOF | |
| Package: perry | |
| Version: ${VERSION} | |
| Section: devel | |
| Priority: optional | |
| Architecture: ${ARCH} | |
| Depends: gcc | clang | |
| Maintainer: Perry Team <hello@perryts.com> | |
| Homepage: https://github.com/PerryTS/perry | |
| Description: Native TypeScript compiler | |
| Perry compiles TypeScript source code directly to native | |
| executables using Cranelift for code generation. | |
| EOF | |
| sed -i 's/^ //' "${PKG}/DEBIAN/control" | |
| cp staging/perry "${PKG}/usr/bin/" | |
| chmod 755 "${PKG}/usr/bin/perry" | |
| for lib in libperry_runtime.a libperry_stdlib.a libperry_ui_gtk4.a; do | |
| if [ -f "staging/$lib" ]; then | |
| cp "staging/$lib" "${PKG}/usr/lib/perry/" | |
| fi | |
| done | |
| # Add library path config so perry can find its libs | |
| mkdir -p "${PKG}/etc/perry" | |
| echo "/usr/lib/perry" > "${PKG}/etc/perry/lib-path" | |
| dpkg-deb --build "${PKG}" | |
| - name: Upload .deb as release asset | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ steps.release.outputs.version }}" | |
| ARCH="${{ matrix.arch }}" | |
| gh release upload "${{ github.event.release.tag_name }}" \ | |
| "perry_${VERSION}_${ARCH}.deb" \ | |
| --repo "${{ github.repository }}" --clobber | |
| - name: Upload .deb artifact (for apt-repo job) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: deb-${{ matrix.arch }} | |
| path: "*.deb" | |
| # --------------------------------------------------------------------------- | |
| # Update APT repository (GitHub Pages) | |
| # --------------------------------------------------------------------------- | |
| apt-repo: | |
| needs: apt | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get release info | |
| id: release | |
| run: | | |
| TAG="${{ github.event.release.tag_name }}" | |
| VERSION="${TAG#v}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Download .deb packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: deb-* | |
| merge-multiple: true | |
| path: debs/ | |
| - name: Clone APT repo | |
| env: | |
| APT_TOKEN: ${{ secrets.APT_REPO_TOKEN }} | |
| run: git clone "https://x-access-token:${APT_TOKEN}@github.com/PerryTS/perry-apt.git" apt-repo | |
| - name: Import GPG key | |
| env: | |
| GPG_PRIVATE_KEY: ${{ secrets.APT_GPG_PRIVATE_KEY }} | |
| run: echo "$GPG_PRIVATE_KEY" | gpg --batch --import | |
| - name: Update repository | |
| env: | |
| GPG_KEY_ID: ${{ secrets.APT_GPG_KEY_ID }} | |
| run: | | |
| cd apt-repo | |
| # Copy new .deb files into pool | |
| mkdir -p pool/main/p/perry | |
| cp ../debs/*.deb pool/main/p/perry/ | |
| # Generate Packages index for each architecture | |
| for ARCH in amd64 arm64; do | |
| mkdir -p dists/stable/main/binary-${ARCH} | |
| dpkg-scanpackages --arch ${ARCH} pool/ > dists/stable/main/binary-${ARCH}/Packages | |
| gzip -9c dists/stable/main/binary-${ARCH}/Packages > dists/stable/main/binary-${ARCH}/Packages.gz | |
| done | |
| # Generate Release file | |
| cd dists/stable | |
| cat > Release << EOF | |
| Origin: PerryTS | |
| Label: Perry | |
| Suite: stable | |
| Codename: stable | |
| Architectures: amd64 arm64 | |
| Components: main | |
| Description: Perry native TypeScript compiler | |
| EOF | |
| sed -i 's/^ //' Release | |
| # Add checksums | |
| { | |
| echo "MD5Sum:" | |
| find main/ -type f | while read f; do | |
| echo " $(md5sum "$f" | cut -d' ' -f1) $(wc -c < "$f") $f" | |
| done | |
| echo "SHA256:" | |
| find main/ -type f | while read f; do | |
| echo " $(sha256sum "$f" | cut -d' ' -f1) $(wc -c < "$f") $f" | |
| done | |
| } >> Release | |
| # Sign | |
| gpg --batch --yes --default-key "${GPG_KEY_ID}" -abs -o Release.gpg Release | |
| gpg --batch --yes --default-key "${GPG_KEY_ID}" --clearsign -o InRelease Release | |
| cd ../.. | |
| # Export public key for users | |
| gpg --armor --export "${GPG_KEY_ID}" > perry.gpg.pub | |
| git config user.name "perry-bot" | |
| git config user.email "bot@perryts.com" | |
| git add -A | |
| git commit -m "perry ${{ steps.release.outputs.version }}" | |
| git push | |
| # --------------------------------------------------------------------------- | |
| # Publish to winget (Windows Package Manager) | |
| # --------------------------------------------------------------------------- | |
| winget: | |
| needs: build | |
| runs-on: windows-latest | |
| steps: | |
| - name: Get release info | |
| id: release | |
| shell: pwsh | |
| run: | | |
| $tag = "${{ github.event.release.tag_name }}" | |
| $version = $tag -replace '^v', '' | |
| echo "version=$version" >> $env:GITHUB_OUTPUT | |
| echo "tag=$tag" >> $env:GITHUB_OUTPUT | |
| - name: Download wingetcreate | |
| shell: pwsh | |
| run: | | |
| Invoke-WebRequest "https://aka.ms/wingetcreate/latest" -OutFile wingetcreate.exe | |
| - name: Update winget manifest | |
| shell: pwsh | |
| env: | |
| WINGET_PAT: ${{ secrets.WINGET_PAT }} | |
| run: | | |
| $url = "https://github.com/${{ github.repository }}/releases/download/${{ steps.release.outputs.tag }}/perry-windows-x86_64.zip" | |
| ./wingetcreate.exe update PerryTS.Perry ` | |
| --urls $url ` | |
| --version "${{ steps.release.outputs.version }}" ` | |
| --token $env:WINGET_PAT ` | |
| --submit | |
| # --------------------------------------------------------------------------- | |
| # Notify build workers to update perry | |
| # --------------------------------------------------------------------------- | |
| update-workers: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get release version | |
| id: release | |
| run: | | |
| TAG="${{ github.event.release.tag_name }}" | |
| VERSION="${TAG#v}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Trigger worker perry update | |
| env: | |
| HUB_ADMIN_SECRET: ${{ secrets.HUB_ADMIN_SECRET }} | |
| run: | | |
| echo "Triggering perry update on build workers (expected: ${{ steps.release.outputs.version }})..." | |
| RESPONSE=$(curl -sf -X POST "https://hub.perryts.com/api/v1/admin/update-perry" \ | |
| -H "Authorization: Bearer ${HUB_ADMIN_SECRET}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"expected_version\": \"${{ steps.release.outputs.version }}\"}" 2>&1) || true | |
| echo "Hub response: ${RESPONSE}" |