- Removed the workflow_dispatch trigger from both release workflows to enforce tag-based releases. - Added a mechanism to wait for draft releases before uploading assets, ensuring all necessary files are present. - Implemented asset upload to GitHub releases and conditional publishing based on asset completeness. - Enhanced SHA256 checksum generation for both production and development binaries.
344 lines
11 KiB
YAML
344 lines
11 KiB
YAML
name: Release macOS
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
# ===================================================================
|
|
# Build Yao macOS binaries (arm64 + amd64) — one job, both arches
|
|
# ===================================================================
|
|
build:
|
|
runs-on: macos-latest
|
|
steps:
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 18
|
|
|
|
- name: Install pnpm
|
|
run: npm install -g pnpm
|
|
|
|
- name: Setup Cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.cache/go-build
|
|
~/go/pkg/mod
|
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-go-
|
|
|
|
- name: Checkout Kun
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/kun
|
|
path: kun
|
|
|
|
- name: Checkout Xun
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/xun
|
|
path: xun
|
|
|
|
- name: Checkout Gou
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/gou
|
|
path: gou
|
|
|
|
- name: Checkout V8Go
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/v8go
|
|
path: v8go
|
|
|
|
- name: Unzip libv8
|
|
run: |
|
|
files=$(find ./v8go -name "libv8*.zip")
|
|
for file in $files; do
|
|
dir=$(dirname "$file")
|
|
echo "Extracting $file to directory $dir"
|
|
unzip -o -d $dir $file
|
|
rm -rf $dir/__MACOSX
|
|
done
|
|
|
|
- name: Checkout CUI v1.0
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/cui
|
|
path: cui-v1.0
|
|
|
|
- name: Checkout Yao-Init
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: yaoapp/yao-init
|
|
path: yao-init
|
|
|
|
- name: Move Dependencies
|
|
run: |
|
|
mv kun ../
|
|
mv xun ../
|
|
mv gou ../
|
|
mv v8go ../
|
|
mv cui-v1.0 ../
|
|
mv yao-init ../
|
|
rm -f ../cui-v1.0/packages/setup/vite.config.ts.*
|
|
|
|
- name: Checkout Yao
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set Version from Tag
|
|
run: |
|
|
if [[ "$GITHUB_REF" != refs/tags/v* ]]; then
|
|
echo "::error::This workflow requires a tag (refs/tags/v*). Got: $GITHUB_REF"
|
|
exit 1
|
|
fi
|
|
TAG="${GITHUB_REF#refs/tags/v}"
|
|
echo "Setting VERSION to $TAG"
|
|
sed -i.bak "s/const VERSION = \".*\"/const VERSION = \"${TAG}\"/g" share/const.go
|
|
rm -f share/const.go.bak
|
|
grep 'const VERSION' share/const.go
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version: "1.25"
|
|
|
|
- name: Setup Go Tools
|
|
run: make tools
|
|
|
|
- name: Make Artifacts macOS
|
|
run: make artifacts-macos
|
|
|
|
- name: Get Version
|
|
id: version
|
|
run: |
|
|
VERSION=$(grep 'const VERSION =' share/const.go | awk '{print $4}' | sed 's/"//g')
|
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
|
|
|
- name: List Build Output
|
|
run: ls -lh dist/release/
|
|
|
|
- name: Install Certificates
|
|
env:
|
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
run: |
|
|
mkdir -p certs
|
|
echo "${{ secrets.APPLE_DEVELOPERIDG2CA }}" | base64 --decode > certs/DeveloperIDG2CA.cer
|
|
echo "${{ secrets.APPLE_DISTRIBUTION }}" | base64 --decode > certs/distribution.cer
|
|
echo "${{ secrets.APPLE_PRIVATE_KEY }}" | base64 --decode > certs/private_key.p12
|
|
security verify-cert -c certs/DeveloperIDG2CA.cer
|
|
security verify-cert -c certs/distribution.cer
|
|
|
|
- name: Import Certificates
|
|
env:
|
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
run: |
|
|
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
security import ./certs/DeveloperIDG2CA.cer -k $KEYCHAIN_PATH -T /usr/bin/codesign
|
|
security import ./certs/distribution.cer -k $KEYCHAIN_PATH -T /usr/bin/codesign
|
|
security import ./certs/private_key.p12 -k $KEYCHAIN_PATH -P "${{ secrets.APPLE_PRIVATE_KEY_PASSWORD }}" -T /usr/bin/codesign
|
|
security list-keychain -d user -s $KEYCHAIN_PATH
|
|
|
|
- name: Sign Yao Binaries
|
|
run: |
|
|
VERSION="${{ steps.version.outputs.version }}"
|
|
IDENTITY="Developer ID Application: ${{ secrets.APPLE_SIGN }}"
|
|
for ARCH in arm64 amd64; do
|
|
for SUFFIX in "" "-prod"; do
|
|
BIN="dist/release/yao-${VERSION}-darwin-${ARCH}${SUFFIX}"
|
|
codesign --force --verbose --timestamp --options runtime \
|
|
--entitlements .github/codesign/entitlements.plist \
|
|
--sign "$IDENTITY" "$BIN"
|
|
codesign --verify --deep --strict --verbose=2 "$BIN"
|
|
done
|
|
done
|
|
|
|
- name: Prepare Output and Checksums
|
|
run: |
|
|
VERSION="${{ steps.version.outputs.version }}"
|
|
for ARCH in arm64 amd64; do
|
|
for VARIANT in dev prod; do
|
|
if [ "$VARIANT" = "dev" ]; then
|
|
SRC="dist/release/yao-${VERSION}-darwin-${ARCH}"
|
|
else
|
|
SRC="dist/release/yao-${VERSION}-darwin-${ARCH}-prod"
|
|
fi
|
|
DIR="/tmp/yao-output-${ARCH}-${VARIANT}"
|
|
mkdir -p "$DIR"
|
|
cp "$SRC" "$DIR/yao"
|
|
chmod +x "$DIR/yao"
|
|
done
|
|
done
|
|
|
|
mkdir -p /tmp/checksums
|
|
for ARCH in arm64 amd64; do
|
|
for VARIANT in dev prod; do
|
|
shasum -a 256 "/tmp/yao-output-${ARCH}-${VARIANT}/yao" | awk '{print $1" yao"}' > "/tmp/checksums/yao-darwin-${ARCH}-${VARIANT}.sha256"
|
|
done
|
|
done
|
|
cat /tmp/checksums/*.sha256
|
|
|
|
- name: Upload Artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: yao-darwin-arm64
|
|
path: /tmp/yao-output-arm64-prod/yao
|
|
|
|
- name: Upload arm64 Dev Binary
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: yao-darwin-arm64-dev
|
|
path: /tmp/yao-output-arm64-dev/yao
|
|
|
|
- name: Upload amd64 Binary
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: yao-darwin-amd64
|
|
path: /tmp/yao-output-amd64-prod/yao
|
|
|
|
- name: Upload amd64 Dev Binary
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: yao-darwin-amd64-dev
|
|
path: /tmp/yao-output-amd64-dev/yao
|
|
|
|
- name: Upload Checksums
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: yao-darwin-checksums
|
|
path: /tmp/checksums/*.sha256
|
|
|
|
# ===================================================================
|
|
# GitHub Release + R2 Upload (macOS binaries)
|
|
# ===================================================================
|
|
release:
|
|
needs: build
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Get Version
|
|
id: version
|
|
run: |
|
|
if [[ "$GITHUB_REF" != refs/tags/v* ]]; then
|
|
echo "::error::This workflow requires a tag. Got: $GITHUB_REF"
|
|
exit 1
|
|
fi
|
|
VERSION="${GITHUB_REF#refs/tags/v}"
|
|
TAG="${GITHUB_REF#refs/tags/}"
|
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
|
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Download macOS Artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: yao-darwin-arm64
|
|
path: artifacts/arm64-prod
|
|
|
|
- name: Download arm64 Dev
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: yao-darwin-arm64-dev
|
|
path: artifacts/arm64-dev
|
|
|
|
- name: Download amd64 Prod
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: yao-darwin-amd64
|
|
path: artifacts/amd64-prod
|
|
|
|
- name: Download amd64 Dev
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: yao-darwin-amd64-dev
|
|
path: artifacts/amd64-dev
|
|
|
|
- name: Download Checksums
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: yao-darwin-checksums
|
|
path: artifacts/checksums
|
|
|
|
- name: Prepare Release Files
|
|
run: |
|
|
VERSION="${{ steps.version.outputs.version }}"
|
|
mkdir -p release
|
|
cp artifacts/arm64-prod/yao "release/yao-${VERSION}-darwin-arm64"
|
|
cp artifacts/amd64-prod/yao "release/yao-${VERSION}-darwin-amd64"
|
|
cp artifacts/arm64-dev/yao "release/yao-${VERSION}-darwin-arm64-dev"
|
|
cp artifacts/amd64-dev/yao "release/yao-${VERSION}-darwin-amd64-dev"
|
|
cp artifacts/checksums/*.sha256 release/ 2>/dev/null || true
|
|
chmod +x release/yao-*
|
|
ls -lh release/
|
|
|
|
- name: Wait for Draft Release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
TAG="${{ steps.version.outputs.tag }}"
|
|
for i in $(seq 1 30); do
|
|
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" &>/dev/null; then
|
|
echo "Draft release found for $TAG."
|
|
exit 0
|
|
fi
|
|
echo "Waiting for draft release... ($i/30)"
|
|
sleep 10
|
|
done
|
|
echo "::error::Timed out waiting for draft release $TAG"
|
|
exit 1
|
|
|
|
- name: Upload Assets to GitHub Release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
TAG="${{ steps.version.outputs.tag }}"
|
|
gh release upload "$TAG" release/* --repo "$GITHUB_REPOSITORY" --clobber
|
|
|
|
- name: Publish Release if Complete
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
TAG="${{ steps.version.outputs.tag }}"
|
|
ASSET_COUNT=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets | length')
|
|
echo "Current assets: $ASSET_COUNT / 16"
|
|
if [ "$ASSET_COUNT" -ge 16 ]; then
|
|
echo "All assets present, publishing release..."
|
|
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false --latest
|
|
else
|
|
echo "Assets incomplete ($ASSET_COUNT/16), waiting for other workflow to publish."
|
|
fi
|
|
|
|
- name: Upload macOS binaries to R2
|
|
env:
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
|
R2_ENDPOINTS: ${{ secrets.R2_ENDPOINTS }}
|
|
R2_BUCKET: ${{ secrets.R2_BUCKET || 'releases' }}
|
|
run: |
|
|
aws configure set default.region us-east-1
|
|
aws configure set default.s3.signature_version s3v4
|
|
|
|
VERSION="${{ steps.version.outputs.version }}"
|
|
PREFIX="yao/${VERSION}"
|
|
|
|
for PLATFORM in darwin-arm64 darwin-amd64; do
|
|
FILE="release/yao-${VERSION}-${PLATFORM}"
|
|
NAME="yao-${VERSION}-${PLATFORM}"
|
|
sha256sum "$FILE" | awk '{print $1}' > "/tmp/${NAME}.sha256"
|
|
|
|
aws s3 cp "$FILE" "s3://${R2_BUCKET}/${PREFIX}/${NAME}" \
|
|
--endpoint-url "$R2_ENDPOINTS" \
|
|
--content-type "application/octet-stream"
|
|
aws s3 cp "/tmp/${NAME}.sha256" "s3://${R2_BUCKET}/${PREFIX}/${NAME}.sha256" \
|
|
--endpoint-url "$R2_ENDPOINTS" \
|
|
--content-type "text/plain"
|
|
echo "Uploaded: ${NAME} + ${NAME}.sha256"
|
|
done
|