name: Build App (macOS) on: workflow_dispatch: inputs: tag: description: 'Release tag to build (e.g. v1.4.5)' required: true jobs: build-macos: name: Build App (macOS) runs-on: macos-latest env: NODE_VERSION: "20" steps: - name: Determine tag id: tag run: | TAG="${{ github.event.inputs.tag }}" if [ -z "$TAG" ]; then TAG=$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' | head -1 | sed 's|.*refs/tags/||') fi echo "Building for tag: ${TAG}" echo "tag=${TAG}" >> $GITHUB_OUTPUT - uses: actions/checkout@v4 with: ref: ${{ steps.tag.outputs.tag }} - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Install Rust stable run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Install system dependencies run: brew install --quiet create-dmg || true - name: Install npm dependencies run: npm ci - name: Build Tauri app run: npm run tauri build - name: Upload to release env: BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }} run: | which jq || brew install jq REPO_API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" TAG="${{ steps.tag.outputs.tag }}" echo "Release tag: ${TAG}" echo "Waiting for release ${TAG} to be available..." RELEASE_ID="" for i in $(seq 1 30); do RELEASE_JSON=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ "${REPO_API}/releases/tags/${TAG}") RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id // empty') if [ -n "${RELEASE_ID}" ] && [ "${RELEASE_ID}" != "null" ]; then echo "Found release: ${TAG} (ID: ${RELEASE_ID})" break fi echo "Attempt ${i}/30: Release not ready yet, retrying in 10s..." sleep 10 done if [ -z "${RELEASE_ID}" ] || [ "${RELEASE_ID}" = "null" ]; then echo "ERROR: Failed to find release for tag ${TAG} after 30 attempts." exit 1 fi find src-tauri/target/release/bundle -type f -name "*.dmg" | while IFS= read -r file; do filename=$(basename "$file") encoded_name=$(echo "$filename" | sed 's/ /%20/g') echo "Uploading ${filename} ($(du -h "$file" | cut -f1))..." ASSET_ID=$(curl -s -H "Authorization: token ${BUILD_TOKEN}" \ "${REPO_API}/releases/${RELEASE_ID}/assets" | jq -r ".[] | select(.name == \"${filename}\") | .id // empty") if [ -n "${ASSET_ID}" ]; then curl -s -X DELETE -H "Authorization: token ${BUILD_TOKEN}" \ "${REPO_API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" fi HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ -H "Authorization: token ${BUILD_TOKEN}" \ -H "Content-Type: application/octet-stream" \ -T "$file" \ "${REPO_API}/releases/${RELEASE_ID}/assets?name=${encoded_name}") echo "Upload response: HTTP ${HTTP_CODE}" done