Skip to content

Merge pull request #402 from wendylabsinc/jo/wendy-lite-gcp #1485

Merge pull request #402 from wendylabsinc/jo/wendy-lite-gcp

Merge pull request #402 from wendylabsinc/jo/wendy-lite-gcp #1485

Workflow file for this run

name: Build products and release
on:
push:
branches: [main]
workflow_dispatch:
inputs:
publish:
description: "Publish artifacts and create a stable release"
type: boolean
default: false
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
# Add permissions needed for creating releases
permissions:
contents: write
jobs:
determine-version:
name: Determine Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-version.outputs.version }}
is_release: ${{ steps.set-version.outputs.is_release }}
is_prerelease: ${{ steps.set-version.outputs.is_prerelease }}
tag_name: ${{ steps.set-version.outputs.tag_name }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set version
id: set-version
run: |
TIMESTAMP=$(date +'%Y.%m.%d-%H%M%S')
if [ "$GITHUB_REF" == "refs/heads/main" ]; then
VERSION="${TIMESTAMP}"
else
VERSION="${TIMESTAMP}-dev"
fi
# Stable release when manually triggered with publish=true
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.publish }}" == "true" ]]; then
IS_RELEASE="true"
IS_PRERELEASE="false"
else
IS_RELEASE="false"
IS_PRERELEASE="true"
fi
TAG_NAME="$VERSION"
echo "version=$VERSION, release=$IS_RELEASE, prerelease=$IS_PRERELEASE"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "is_release=$IS_RELEASE" >> $GITHUB_OUTPUT
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
build:
name: ${{ matrix.artifact-name }}
runs-on: ubuntu-latest
needs: [determine-version]
strategy:
matrix:
include:
- artifact-name: wendy-agent-linux-amd64
goos: linux
goarch: amd64
product: wendy-agent
cmd: wendy-agent
- artifact-name: wendy-agent-linux-arm64
goos: linux
goarch: arm64
product: wendy-agent
cmd: wendy-agent
- artifact-name: wendy-cli-linux-amd64
goos: linux
goarch: amd64
product: wendy
cmd: wendy
- artifact-name: wendy-cli-linux-arm64
goos: linux
goarch: arm64
product: wendy
cmd: wendy
- artifact-name: wendy-cli-windows-amd64
goos: windows
goarch: amd64
product: wendy.exe
cmd: wendy
- artifact-name: wendy-cli-windows-arm64
goos: windows
goarch: arm64
product: wendy.exe
cmd: wendy
defaults:
run:
working-directory: go
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go/go.mod
cache-dependency-path: go/go.sum
- name: Build
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
LDFLAGS="-s -w -X github.com/wendylabsinc/wendy/internal/shared/version.Version=${VERSION}"
mkdir -p ../${{ matrix.artifact-name }}
go build -ldflags "${LDFLAGS}" -o ../${{ matrix.artifact-name }}/${{ matrix.product }} ./cmd/${{ matrix.cmd }}
- name: Create archive
working-directory: .
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
if [[ "${{ matrix.goos }}" == "windows" ]]; then
ARCHIVE="${{ matrix.artifact-name }}-${VERSION}.zip"
apt-get update && apt-get install -y zip
zip -r "$ARCHIVE" ${{ matrix.artifact-name }}/
else
ARCHIVE="${{ matrix.artifact-name }}-${VERSION}.tar.gz"
tar -czvf "$ARCHIVE" ${{ matrix.artifact-name }}/
fi
echo "archive=$ARCHIVE" >> $GITHUB_ENV
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.archive }}
path: ${{ env.archive }}
retention-days: 14
if-no-files-found: error
build-go-macos:
name: ${{ matrix.artifact-name }}
runs-on: macos-15
needs: [determine-version]
strategy:
matrix:
include:
- artifact-name: wendy-cli-darwin-arm64
goarch: arm64
- artifact-name: wendy-cli-darwin-amd64
goarch: amd64
defaults:
run:
working-directory: go
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go/go.mod
cache-dependency-path: go/go.sum
- name: Build
env:
CGO_ENABLED: "1"
GOOS: darwin
GOARCH: ${{ matrix.goarch }}
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
LDFLAGS="-s -w -X github.com/wendylabsinc/wendy/internal/shared/version.Version=${VERSION}"
mkdir -p ../${{ matrix.artifact-name }}
go build -ldflags "${LDFLAGS}" -o ../${{ matrix.artifact-name }}/wendy ./cmd/wendy
- name: Create archive
working-directory: .
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
ARCHIVE="${{ matrix.artifact-name }}-${VERSION}.tar.gz"
tar -czvf "$ARCHIVE" ${{ matrix.artifact-name }}/
echo "archive=$ARCHIVE" >> $GITHUB_ENV
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.archive }}
path: ${{ env.archive }}
retention-days: 14
if-no-files-found: error
package-linux:
name: Package Linux (${{ matrix.arch }})
runs-on: ubuntu-latest
needs: [determine-version, build]
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish == true)
strategy:
matrix:
include:
- arch: amd64
goarch: amd64
rpm-arch: x86_64
- arch: arm64
goarch: arm64
rpm-arch: aarch64
steps:
- uses: actions/checkout@v4
- name: Install FPM dependencies
run: |
sudo apt-get update
sudo apt-get install -y ruby ruby-dev build-essential rpm
sudo gem install fpm
- name: Download CLI artifact
uses: actions/download-artifact@v4
with:
name: wendy-cli-linux-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.tar.gz
- name: Download Agent artifact
uses: actions/download-artifact@v4
with:
name: wendy-agent-linux-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.tar.gz
- name: Extract artifacts
run: |
ls -la
tar -xzf wendy-cli-linux-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.tar.gz
tar -xzf wendy-agent-linux-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.tar.gz
ls -la
- name: Prepare package roots
run: |
set -euo pipefail
mkdir -p pkgroot/wendy/usr/bin
mkdir -p pkgroot/wendy-agent/usr/bin
mkdir -p pkgroot/wendy-agent/usr/lib/systemd/system
mkdir -p pkgroot/wendy-agent/usr/lib/wendy-agent
mkdir -p pkgroot/wendy-agent/etc/default
mkdir -p pkgroot/wendy-agent/etc/wendy-agent
mkdir -p pkgroot/wendy-agent/etc/avahi/services
mkdir -p pkgroot/wendy-agent/var/lib/wendy-agent/storage
install -m755 ./wendy-cli-linux-${{ matrix.goarch }}/wendy \
pkgroot/wendy/usr/bin/wendy
install -m755 ./wendy-agent-linux-${{ matrix.goarch }}/wendy-agent \
pkgroot/wendy-agent/usr/bin/wendy-agent
install -m644 packaging/linux/systemd/wendy-agent.service \
pkgroot/wendy-agent/usr/lib/systemd/system/wendy-agent.service
install -m644 packaging/linux/default/wendy-agent \
pkgroot/wendy-agent/etc/default/wendy-agent
install -m644 packaging/linux/avahi/wendy-agent.service \
pkgroot/wendy-agent/etc/avahi/services/wendy-agent.service
install -m755 packaging/linux/fpm/wendy-agent-setup-mdns.sh \
pkgroot/wendy-agent/usr/lib/wendy-agent/setup-mdns.sh
# Placeholder config created at install time by package manager.
printf "{}\n" > pkgroot/wendy-agent/etc/wendy-agent/config.json
chmod 600 pkgroot/wendy-agent/etc/wendy-agent/config.json
- name: Build .deb packages
run: |
set -euo pipefail
VERSION="${{ needs.determine-version.outputs.version }}"
# Build wendy .deb
fpm -s dir -t deb \
-n wendy \
-v "$VERSION" \
--architecture ${{ matrix.arch }} \
--description "Wendy CLI - Remote device debugging and deployment" \
--url "https://wendy.sh" \
--maintainer "Wendy Labs Inc. <support@wendy.sh>" \
--license "Proprietary" \
--vendor "Wendy Labs Inc." \
--category "devel" \
--depends "usbutils" \
--depends "ca-certificates" \
-C pkgroot/wendy \
.
# Build wendy-agent .deb
fpm -s dir -t deb \
-n wendy-agent \
-v "$VERSION" \
--architecture ${{ matrix.arch }} \
--description "Wendy Agent - Runs on target devices for remote debugging" \
--url "https://wendy.sh" \
--maintainer "Wendy Labs Inc. <support@wendy.sh>" \
--license "Proprietary" \
--vendor "Wendy Labs Inc." \
--category "devel" \
--depends "containerd" \
--depends "xdg-dbus-proxy" \
--depends "dbus" \
--depends "systemd" \
--depends "ca-certificates" \
--depends "avahi-daemon" \
--deb-recommends "nerdctl" \
--deb-recommends "network-manager | connman" \
--deb-recommends "bluez" \
--config-files /etc/default/wendy-agent \
--config-files /etc/wendy-agent/config.json \
--config-files /etc/avahi/services/wendy-agent.service \
--after-install packaging/linux/fpm/wendy-agent-postinstall.sh \
--before-remove packaging/linux/fpm/wendy-agent-preremove.sh \
-C pkgroot/wendy-agent \
.
ls -la *.deb
- name: Build .rpm packages
run: |
set -euo pipefail
VERSION="${{ needs.determine-version.outputs.version }}"
# RPM doesn't allow hyphens in version, replace with underscores
RPM_VERSION=$(echo "$VERSION" | tr '-' '_')
# Build wendy .rpm
fpm -s dir -t rpm \
-n wendy \
-v "$RPM_VERSION" \
--architecture ${{ matrix.rpm-arch }} \
--description "Wendy CLI - Remote device debugging and deployment" \
--url "https://wendy.sh" \
--maintainer "Wendy Labs Inc. <support@wendy.sh>" \
--license "Proprietary" \
--vendor "Wendy Labs Inc." \
--category "Development/Tools" \
--depends "usbutils" \
--depends "ca-certificates" \
-C pkgroot/wendy \
.
# Build wendy-agent .rpm
fpm -s dir -t rpm \
-n wendy-agent \
-v "$RPM_VERSION" \
--architecture ${{ matrix.rpm-arch }} \
--description "Wendy Agent - Runs on target devices for remote debugging" \
--url "https://wendy.sh" \
--maintainer "Wendy Labs Inc. <support@wendy.sh>" \
--license "Proprietary" \
--vendor "Wendy Labs Inc." \
--category "Development/Tools" \
--depends "containerd" \
--depends "xdg-dbus-proxy" \
--depends "dbus" \
--depends "systemd" \
--depends "ca-certificates" \
--depends "avahi" \
--config-files /etc/default/wendy-agent \
--config-files /etc/wendy-agent/config.json \
--config-files /etc/avahi/services/wendy-agent.service \
--after-install packaging/linux/fpm/wendy-agent-postinstall.sh \
--before-remove packaging/linux/fpm/wendy-agent-preremove.sh \
-C pkgroot/wendy-agent \
.
ls -la *.rpm
- name: Validate package metadata
run: |
set -euo pipefail
WENDY_DEB=$(ls -1 wendy_*_${{ matrix.arch }}.deb | head -1)
WENDY_AGENT_DEB=$(ls -1 wendy-agent_*_${{ matrix.arch }}.deb | head -1)
WENDY_RPM=$(ls -1 wendy-[0-9]*.rpm | head -1)
WENDY_AGENT_RPM=$(ls -1 wendy-agent-*.rpm | head -1)
dpkg-deb -I "$WENDY_DEB" | grep -E "Depends:.*usbutils"
dpkg-deb -I "$WENDY_DEB" | grep -E "Depends:.*ca-certificates"
dpkg-deb -I "$WENDY_AGENT_DEB" | grep -E "Depends:.*containerd"
dpkg-deb -I "$WENDY_AGENT_DEB" | grep -E "Depends:.*dbus"
dpkg-deb -I "$WENDY_AGENT_DEB" | grep -E "Depends:.*systemd"
dpkg-deb -I "$WENDY_AGENT_DEB" | grep -E "Depends:.*ca-certificates"
dpkg-deb -c "$WENDY_AGENT_DEB" | grep "usr/lib/systemd/system/wendy-agent.service" > /dev/null
dpkg-deb -c "$WENDY_AGENT_DEB" | grep "etc/default/wendy-agent" > /dev/null
dpkg-deb -c "$WENDY_AGENT_DEB" | grep "etc/avahi/services/wendy-agent.service" > /dev/null
dpkg-deb -I "$WENDY_AGENT_DEB" | grep -E "Depends:.*avahi-daemon"
rpm -qp --requires "$WENDY_RPM" | grep "^usbutils" > /dev/null
rpm -qp --requires "$WENDY_RPM" | grep "^ca-certificates" > /dev/null
rpm -qp --requires "$WENDY_AGENT_RPM" | grep "^containerd" > /dev/null
rpm -qp --requires "$WENDY_AGENT_RPM" | grep "^dbus" > /dev/null
rpm -qp --requires "$WENDY_AGENT_RPM" | grep "^systemd" > /dev/null
rpm -qp --requires "$WENDY_AGENT_RPM" | grep "^ca-certificates" > /dev/null
rpm -qp --requires "$WENDY_AGENT_RPM" | grep "^avahi" > /dev/null
rpm -qpl "$WENDY_AGENT_RPM" | grep "/usr/lib/systemd/system/wendy-agent.service" > /dev/null
rpm -qpl "$WENDY_AGENT_RPM" | grep "/etc/default/wendy-agent" > /dev/null
rpm -qpl "$WENDY_AGENT_RPM" | grep "/etc/avahi/services/wendy-agent.service" > /dev/null
- name: Upload .deb packages
uses: actions/upload-artifact@v4
with:
name: linux-packages-deb-${{ matrix.arch }}
path: "*.deb"
retention-days: 14
- name: Upload .rpm packages
uses: actions/upload-artifact@v4
with:
name: linux-packages-rpm-${{ matrix.arch }}
path: "*.rpm"
retention-days: 14
package-windows:
name: Package Windows MSI (${{ matrix.arch }})
runs-on: windows-latest
needs: [determine-version, build]
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish == true)
strategy:
matrix:
include:
- arch: amd64
goarch: amd64
- arch: arm64
goarch: arm64
steps:
- uses: actions/checkout@v4
- name: Install WiX
run: dotnet tool install --global wix
- name: Download CLI artifact
uses: actions/download-artifact@v4
with:
name: wendy-cli-windows-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.zip
- name: Extract artifact
run: |
Expand-Archive "wendy-cli-windows-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.zip" -DestinationPath .
- name: Build MSI
run: |
$VERSION = "${{ needs.determine-version.outputs.version }}"
# MSI requires numeric X.Y.Z version (max 255.255.65535)
if ($VERSION -match '^\d+\.\d+\.\d+') {
$MSI_VERSION = $Matches[0]
} else {
$MSI_VERSION = "0.0.0"
}
$MSI_ARCH = if ("${{ matrix.arch }}" -eq "arm64") { "arm64" } else { "x64" }
wix build `
-d Version="$MSI_VERSION" `
-d ExePath="wendy-cli-windows-${{ matrix.goarch }}/wendy.exe" `
-arch $MSI_ARCH `
-o "wendy-cli-windows-${{ matrix.goarch }}-${VERSION}.msi" `
go/installer/windows/wendy.wxs
- name: Upload MSI
uses: actions/upload-artifact@v4
with:
name: wendy-cli-windows-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.msi
path: "wendy-cli-windows-${{ matrix.goarch }}-${{ needs.determine-version.outputs.version }}.msi"
retention-days: 14
if-no-files-found: error
publish-linux-repos:
name: Publish to GCP Artifact Registry
runs-on: ubuntu-latest
needs: [determine-version, package-linux]
if: needs.determine-version.outputs.is_release == 'true' && needs.determine-version.outputs.is_prerelease == 'false'
permissions:
contents: read
id-token: write
steps:
- name: Download all .deb packages
uses: actions/download-artifact@v4
with:
pattern: linux-packages-deb-*
merge-multiple: true
path: packages/deb
- name: Download all .rpm packages
uses: actions/download-artifact@v4
with:
pattern: linux-packages-rpm-*
merge-multiple: true
path: packages/rpm
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ vars.GCP_SERVICE_ACCOUNT }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Upload APT packages
run: |
echo "Uploading .deb packages to Artifact Registry..."
for deb in packages/deb/*.deb; do
echo "Uploading $deb"
gcloud artifacts apt upload wendy-apt \
--location=us-central1 \
--project=${{ vars.GCP_PROJECT_ID }} \
--source="$deb"
done
- name: Upload YUM packages
run: |
echo "Uploading .rpm packages to Artifact Registry..."
for rpm in packages/rpm/*.rpm; do
echo "Uploading $rpm"
gcloud artifacts yum upload wendy-yum \
--location=us-central1 \
--project=${{ vars.GCP_PROJECT_ID }} \
--source="$rpm"
done
release:
name: Release
runs-on: ubuntu-latest
needs: [determine-version, build, build-go-macos, package-linux, package-windows]
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish == true)
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: List files
run: |
ls -la
# Create a newline-delimited list of release files
{
echo 'FILES<<EOF'
find . -name "*.tar.gz" -o -name "*.zip" -o -name "*.msi" -o -name "*.deb" -o -name "*.rpm" | sort
echo 'EOF'
} >> $GITHUB_ENV
- name: Create Release
id: create_release
uses: softprops/action-gh-release@v2
with:
name: ${{ needs.determine-version.outputs.version }}
tag_name: ${{ needs.determine-version.outputs.tag_name }}
draft: false
prerelease: ${{ needs.determine-version.outputs.is_prerelease == 'true' }}
make_latest: ${{ needs.determine-version.outputs.is_prerelease == 'false' }}
files: ${{ env.FILES }}
generate_release_notes: true
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Update floating 'latest' tag for nightly prereleases
- name: Checkout repo
if: needs.determine-version.outputs.is_release != 'true'
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Update 'latest' tag
if: needs.determine-version.outputs.is_release != 'true'
run: |
set -euo pipefail
git fetch origin --tags --force
TAG='${{ needs.determine-version.outputs.tag_name }}'
TARGET_SHA="$(git rev-list -n 1 "refs/tags/$TAG" || true)"
if [ -z "$TARGET_SHA" ]; then TARGET_SHA="$GITHUB_SHA"; fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -fa latest "$TARGET_SHA" -m "Latest prerelease: $TAG"
git push -f origin refs/tags/latest
# Discord notification for stable releases
- name: Notify Discord
if: needs.determine-version.outputs.is_prerelease == 'false'
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ needs.determine-version.outputs.tag_name }}"
REPO="${{ github.repository }}"
URL="https://github.com/${REPO}/releases/tag/${VERSION}"
# Fetch release body via gh CLI (safe from shell injection)
BODY=$(gh release view "$VERSION" --repo "$REPO" --json body -q .body 2>/dev/null || echo "")
BODY=$(echo "$BODY" | tr -d '\r')
SHORT_BODY=$(echo "$BODY" | head -c 800)
# Installation instructions
read -r -d '' INSTALL_INSTRUCTIONS << 'INSTALL_EOF' || true
## Install the Wendy CLI
**Linux/macOS**
```
curl -fsSL https://install.wendy.sh/cli.sh | bash
```
## Install the Wendy Agent
**Linux/macOS**
```
curl -fsSL https://install.wendy.sh/agent.sh | bash
```
INSTALL_EOF
FULL_DESCRIPTION="${SHORT_BODY}
${INSTALL_INSTRUCTIONS}"
ESCAPED_DESC=$(echo "$FULL_DESCRIPTION" | jq -Rs .)
cat > /tmp/discord_payload.json << PAYLOAD_EOF
{
"content": "🚀 **New CLI release**: **${VERSION}**",
"embeds": [
{
"title": "Release ${VERSION}",
"url": "${URL}",
"description": ${ESCAPED_DESC},
"color": 5814783,
"footer": { "text": "${REPO} • ${VERSION}" }
}
]
}
PAYLOAD_EOF
if [ -n "$DISCORD_WEBHOOK_URL" ]; then
curl -sS -X POST -H "Content-Type: application/json" \
-d @/tmp/discord_payload.json \
"$DISCORD_WEBHOOK_URL" && echo "Discord notification sent" || echo "Discord notification failed"
else
echo "DISCORD_WEBHOOK_URL not configured, skipping notification"
fi
# Bump the formula in homebrew-tap
- name: Create GitHub App Token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.CLI_PUBLISHER_APP_ID }}
private-key: ${{ secrets.CLI_PUBLISHER_APP_PRIVATE_KEY }}
owner: wendylabsinc
repositories: homebrew-tap
- name: Checkout tap
uses: actions/checkout@v4
with:
repository: wendylabsinc/homebrew-tap
token: ${{ steps.app-token.outputs.token }}
ref: main
path: tap
- name: Calculate binary checksums
id: checksums
run: |
set -euo pipefail
VERSION="${{ needs.determine-version.outputs.version }}"
TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
MACOS_URL="https://github.com/wendylabsinc/wendy-agent/releases/download/${TAG_NAME}/wendy-cli-darwin-arm64-${VERSION}.tar.gz"
MACOS_SHA=$(curl -fsSL "$MACOS_URL" | sha256sum | awk '{print $1}')
LINUX_ARM_URL="https://github.com/wendylabsinc/wendy-agent/releases/download/${TAG_NAME}/wendy-cli-linux-arm64-${VERSION}.tar.gz"
LINUX_ARM_SHA=$(curl -fsSL "$LINUX_ARM_URL" | sha256sum | awk '{print $1}')
LINUX_X86_URL="https://github.com/wendylabsinc/wendy-agent/releases/download/${TAG_NAME}/wendy-cli-linux-amd64-${VERSION}.tar.gz"
LINUX_X86_SHA=$(curl -fsSL "$LINUX_X86_URL" | sha256sum | awk '{print $1}')
echo "URLs and SHA256s:"
echo " macOS ARM64: ${MACOS_URL} -> ${MACOS_SHA}"
echo " Linux ARM64: ${LINUX_ARM_URL} -> ${LINUX_ARM_SHA}"
echo " Linux x86_64: ${LINUX_X86_URL} -> ${LINUX_X86_SHA}"
echo "macos_url=${MACOS_URL}" >> $GITHUB_OUTPUT
echo "macos_sha=${MACOS_SHA}" >> $GITHUB_OUTPUT
echo "linux_arm_url=${LINUX_ARM_URL}" >> $GITHUB_OUTPUT
echo "linux_arm_sha=${LINUX_ARM_SHA}" >> $GITHUB_OUTPUT
echo "linux_x86_url=${LINUX_X86_URL}" >> $GITHUB_OUTPUT
echo "linux_x86_sha=${LINUX_X86_SHA}" >> $GITHUB_OUTPUT
# Nightly: update wendy-nightly.rb and push directly to main
- name: Bump nightly formula
if: needs.determine-version.outputs.is_release != 'true'
run: |
set -euo pipefail
cd tap
VERSION="${{ needs.determine-version.outputs.version }}"
FORMULA="Formula/wendy-nightly.rb"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-darwin-arm64[^\"]*|${{ steps.checksums.outputs.macos_url }}|" "$FORMULA"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-linux-arm64[^\"]*|${{ steps.checksums.outputs.linux_arm_url }}|" "$FORMULA"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-linux-amd64[^\"]*|${{ steps.checksums.outputs.linux_x86_url }}|" "$FORMULA"
sed -i "/wendy-cli-darwin-arm64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.macos_sha }}\"|" "$FORMULA"
sed -i "/wendy-cli-linux-arm64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.linux_arm_sha }}\"|" "$FORMULA"
sed -i "/wendy-cli-linux-amd64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.linux_x86_sha }}\"|" "$FORMULA"
# Update bottle root_url version
sed -i "s|wendy-nightly-[^\"]*|wendy-nightly-${VERSION}|" "$FORMULA"
# Verify all URLs and checksums were actually updated
echo "Verifying formula was updated correctly..."
grep -q "wendy-cli-darwin-arm64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update macOS URL in formula"; exit 1; }
grep -q "wendy-cli-linux-arm64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update Linux ARM64 URL in formula"; exit 1; }
grep -q "wendy-cli-linux-amd64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update Linux AMD64 URL in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.macos_sha }}" "$FORMULA" || { echo "::error::Failed to update macOS SHA256 in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.linux_arm_sha }}" "$FORMULA" || { echo "::error::Failed to update Linux ARM64 SHA256 in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.linux_x86_sha }}" "$FORMULA" || { echo "::error::Failed to update Linux AMD64 SHA256 in formula"; exit 1; }
echo "Updated nightly formula:"
grep -A 1 "url\|sha256" "$FORMULA" | head -20
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add "$FORMULA"
git commit -m "wendy-nightly: update to ${VERSION}"
git push origin main
# Stable: update wendy.rb via PR
- name: Bump stable formula
if: needs.determine-version.outputs.is_release == 'true' && needs.determine-version.outputs.is_prerelease == 'false'
run: |
set -euo pipefail
cd tap
VERSION="${{ needs.determine-version.outputs.version }}"
BRANCH="ci/bump-wendy-${VERSION}"
FORMULA="Formula/wendy.rb"
git checkout -b "$BRANCH"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-darwin-arm64[^\"]*|${{ steps.checksums.outputs.macos_url }}|" "$FORMULA"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-linux-arm64[^\"]*|${{ steps.checksums.outputs.linux_arm_url }}|" "$FORMULA"
sed -i "s|https://github.com/wendylabsinc/wendy-agent/releases/download/[^/]*/wendy-cli-linux-amd64[^\"]*|${{ steps.checksums.outputs.linux_x86_url }}|" "$FORMULA"
sed -i "/wendy-cli-darwin-arm64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.macos_sha }}\"|" "$FORMULA"
sed -i "/wendy-cli-linux-arm64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.linux_arm_sha }}\"|" "$FORMULA"
sed -i "/wendy-cli-linux-amd64.*tar\.gz/,/sha256/ s|sha256 \"[^\"]*\"|sha256 \"${{ steps.checksums.outputs.linux_x86_sha }}\"|" "$FORMULA"
# Update bottle root_url version
sed -i "s|wendy-[0-9][^\"]*|wendy-${VERSION}|" "$FORMULA"
# Verify all URLs and checksums were actually updated
echo "Verifying formula was updated correctly..."
grep -q "wendy-cli-darwin-arm64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update macOS URL in formula"; exit 1; }
grep -q "wendy-cli-linux-arm64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update Linux ARM64 URL in formula"; exit 1; }
grep -q "wendy-cli-linux-amd64-${VERSION}" "$FORMULA" || { echo "::error::Failed to update Linux AMD64 URL in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.macos_sha }}" "$FORMULA" || { echo "::error::Failed to update macOS SHA256 in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.linux_arm_sha }}" "$FORMULA" || { echo "::error::Failed to update Linux ARM64 SHA256 in formula"; exit 1; }
grep -q "${{ steps.checksums.outputs.linux_x86_sha }}" "$FORMULA" || { echo "::error::Failed to update Linux AMD64 SHA256 in formula"; exit 1; }
echo "Updated stable formula:"
grep -A 1 "url\|sha256" "$FORMULA" | head -20
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add "$FORMULA"
git commit -m "wendy: bump to ${VERSION}"
git push -u origin "$BRANCH"
- name: Create PR
if: needs.determine-version.outputs.is_release == 'true' && needs.determine-version.outputs.is_prerelease == 'false'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
gh pr create \
--repo wendylabsinc/homebrew-tap \
--head "ci/bump-wendy-${VERSION}" \
--base main \
--title "wendy: bump to ${VERSION}" \
--label pr-pull \
--body "Automated bump from release ${VERSION}
This PR updates the wendy formula to version ${VERSION}.
All platforms use pre-built Go binaries."
publish-aur:
name: Publish AUR Packages
runs-on: ubuntu-latest
needs: [determine-version, release]
if: needs.determine-version.outputs.is_release == 'true' && needs.determine-version.outputs.is_prerelease == 'false'
strategy:
matrix:
include:
- pkgname: wendy
pkgbuild_path: packaging/arch/wendy/PKGBUILD
x86_64_artifact: wendy-cli-linux-amd64
aarch64_artifact: wendy-cli-linux-arm64
- pkgname: wendy-agent
pkgbuild_path: packaging/arch/wendy-agent/PKGBUILD
x86_64_artifact: wendy-agent-linux-amd64
aarch64_artifact: wendy-agent-linux-arm64
steps:
- uses: actions/checkout@v4
- name: Calculate checksums from release
id: checksums
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
# Download and calculate SHA256 for x86_64
X86_64_URL="https://github.com/wendylabsinc/wendy-agent/releases/download/${TAG_NAME}/${{ matrix.x86_64_artifact }}-${VERSION}.tar.gz"
echo "Downloading $X86_64_URL"
X86_64_SHA=$(curl -fsSL "$X86_64_URL" | sha256sum | awk '{print $1}')
echo "x86_64_sha=${X86_64_SHA}" >> $GITHUB_OUTPUT
# Download and calculate SHA256 for aarch64
AARCH64_URL="https://github.com/wendylabsinc/wendy-agent/releases/download/${TAG_NAME}/${{ matrix.aarch64_artifact }}-${VERSION}.tar.gz"
echo "Downloading $AARCH64_URL"
AARCH64_SHA=$(curl -fsSL "$AARCH64_URL" | sha256sum | awk '{print $1}')
echo "aarch64_sha=${AARCH64_SHA}" >> $GITHUB_OUTPUT
echo "Checksums:"
echo " x86_64: ${X86_64_SHA}"
echo " aarch64: ${AARCH64_SHA}"
- name: Update PKGBUILD
run: |
VERSION="${{ needs.determine-version.outputs.version }}"
TAG_NAME="${{ needs.determine-version.outputs.tag_name }}"
PKGBUILD="${{ matrix.pkgbuild_path }}"
# Update version and tag
sed -i "s/^_pkgver=.*/_pkgver=${VERSION}/" "$PKGBUILD"
sed -i "s/^_pkgtag=.*/_pkgtag=${TAG_NAME}/" "$PKGBUILD"
# Update checksums
sed -i "s/sha256sums_x86_64=.*/sha256sums_x86_64=('${{ steps.checksums.outputs.x86_64_sha }}')/" "$PKGBUILD"
sed -i "s/sha256sums_aarch64=.*/sha256sums_aarch64=('${{ steps.checksums.outputs.aarch64_sha }}')/" "$PKGBUILD"
echo "Updated PKGBUILD:"
cat "$PKGBUILD"
- name: Generate .SRCINFO
uses: docker://archlinux:latest
with:
entrypoint: /bin/bash
args: |
-c "
pacman -Sy --noconfirm base-devel shadow
cd $(dirname ${{ matrix.pkgbuild_path }})
if ! id -u builder >/dev/null 2>&1; then
useradd -m builder
fi
chown -R builder:builder .
su builder -s /bin/bash -c 'makepkg --printsrcinfo > .SRCINFO'
cat .SRCINFO
"
- name: Publish to AUR
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
with:
pkgname: ${{ matrix.pkgname }}
pkgbuild: ${{ matrix.pkgbuild_path }}
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: "Update to ${{ needs.determine-version.outputs.version }}"
publish-winget:
name: Publish to Winget
runs-on: windows-latest
needs: [determine-version, release]
if: needs.determine-version.outputs.is_release == 'true' && needs.determine-version.outputs.is_prerelease == 'false'
steps:
- name: Install wingetcreate
run: |
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
- name: Update Winget package
run: |
$version = "${{ needs.determine-version.outputs.version }}"
$tag = "${{ needs.determine-version.outputs.tag_name }}"
$base = "https://github.com/wendylabsinc/wendy-agent/releases/download/$tag"
$token = "${{ secrets.WINGET_GITHUB_TOKEN }}"
$amd64 = "$base/wendy-cli-windows-amd64-$version.msi"
$arm64 = "$base/wendy-cli-windows-arm64-$version.msi"
# Try update first; if the package doesn't exist yet, fall back to new
.\wingetcreate.exe update WendyLabs.Wendy `
--version $version `
--urls $amd64 $arm64 `
--submit `
--token $token
if ($LASTEXITCODE -ne 0) {
Write-Host "Update failed, attempting initial submission with 'new'..."
.\wingetcreate.exe new $amd64 $arm64 `
--version $version `
--id WendyLabs.Wendy `
--name Wendy `
--publisher "Wendy Labs" `
--submit `
--token $token
if ($LASTEXITCODE -ne 0) {
Write-Error "Winget package submission failed (update and new both failed) with exit code $LASTEXITCODE."
exit $LASTEXITCODE
}
}
if ($LASTEXITCODE -ne 0) {
Write-Error "Winget package publication failed with exit code $LASTEXITCODE."
exit $LASTEXITCODE
}