Build Plugin #31
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: Build Plugin | |
| on: | |
| push: | |
| tags: ["plugin-*-v*"] | |
| workflow_dispatch: | |
| inputs: | |
| tags: | |
| description: "Plugin tags, comma-separated (e.g., plugin-oracle-v1.0.1,plugin-sqlite-v1.0.1)" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| env: | |
| XCODE_PROJECT: TablePro.xcodeproj | |
| jobs: | |
| build-plugin: | |
| name: Build Plugin | |
| runs-on: self-hosted | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Install Git LFS | |
| run: brew list git-lfs &>/dev/null || brew install git-lfs; git lfs install | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Pull LFS files | |
| run: git lfs pull | |
| - name: Build and release plugins | |
| env: | |
| REGISTRY_DEPLOY_KEY: ${{ secrets.REGISTRY_DEPLOY_KEY }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| # Build tag list: from input (comma-separated) or from push event (single tag) | |
| if [ -n "${{ inputs.tags }}" ]; then | |
| IFS=',' read -ra TAGS <<< "${{ inputs.tags }}" | |
| else | |
| TAGS=("${{ github.ref_name }}") | |
| fi | |
| # Get current app version for minAppVersion | |
| MIN_APP_VERSION=$(sed -n 's/.*MARKETING_VERSION = \(.*\);/\1/p' \ | |
| TablePro.xcodeproj/project.pbxproj | head -1 | tr -d ' ') | |
| resolve_plugin_info() { | |
| local plugin_name=$1 | |
| case "$plugin_name" in | |
| oracle) | |
| TARGET="OracleDriver"; BUNDLE_ID="com.TablePro.OracleDriver" | |
| DISPLAY_NAME="Oracle Driver"; SUMMARY="Oracle Database 12c+ driver via OracleNIO" | |
| DB_TYPE_IDS='["Oracle"]'; ICON="server.rack"; BUNDLE_NAME="OracleDriver" | |
| HOMEPAGE="https://tablepro.app/databases/oracle" ;; | |
| clickhouse) | |
| TARGET="ClickHouseDriver"; BUNDLE_ID="com.TablePro.ClickHouseDriver" | |
| DISPLAY_NAME="ClickHouse Driver"; SUMMARY="ClickHouse OLAP database driver via HTTP interface" | |
| DB_TYPE_IDS='["ClickHouse"]'; ICON="chart.bar.xaxis"; BUNDLE_NAME="ClickHouseDriver" | |
| HOMEPAGE="https://tablepro.app/databases/clickhouse" ;; | |
| sqlite) | |
| TARGET="SQLiteDriver"; BUNDLE_ID="com.TablePro.SQLiteDriver" | |
| DISPLAY_NAME="SQLite Driver"; SUMMARY="SQLite embedded database driver" | |
| DB_TYPE_IDS='["SQLite"]'; ICON="internaldrive"; BUNDLE_NAME="SQLiteDriver" | |
| HOMEPAGE="https://tablepro.app" ;; | |
| duckdb) | |
| TARGET="DuckDBDriver"; BUNDLE_ID="com.TablePro.DuckDBDriver" | |
| DISPLAY_NAME="DuckDB Driver"; SUMMARY="DuckDB analytical database driver" | |
| DB_TYPE_IDS='["DuckDB"]'; ICON="bird"; BUNDLE_NAME="DuckDBDriver" | |
| HOMEPAGE="https://tablepro.app" ;; | |
| *) echo "Unknown plugin: $plugin_name"; return 1 ;; | |
| esac | |
| } | |
| for TAG in "${TAGS[@]}"; do | |
| TAG=$(echo "$TAG" | xargs) # trim whitespace | |
| echo "" | |
| echo "========================================" | |
| echo "Processing: $TAG" | |
| echo "========================================" | |
| PLUGIN_NAME=$(echo "$TAG" | sed -E 's/^plugin-([a-z]+)-v.*$/\1/') | |
| VERSION=$(echo "$TAG" | sed -E 's/^plugin-[a-z]+-v(.*)$/\1/') | |
| resolve_plugin_info "$PLUGIN_NAME" || continue | |
| echo "Building $TARGET v$VERSION" | |
| # Build both architectures | |
| ./scripts/build-plugin.sh "$TARGET" arm64 | |
| ./scripts/build-plugin.sh "$TARGET" x86_64 | |
| # Capture SHA-256 | |
| ARM64_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-arm64.zip.sha256") | |
| X86_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-x86_64.zip.sha256") | |
| # Notarize if enabled | |
| if [ "${NOTARIZE_PLUGINS:-}" = "true" ]; then | |
| for zip in build/Plugins/${BUNDLE_NAME}-*.zip; do | |
| xcrun notarytool submit "$zip" \ | |
| --apple-id "$APPLE_ID" \ | |
| --team-id "D7HJ5TFYCU" \ | |
| --keychain-profile "notarytool-profile" \ | |
| --wait | |
| done | |
| fi | |
| # Create GitHub Release | |
| RELEASE_BODY="## $DISPLAY_NAME v$VERSION | |
| Plugin release for TablePro. | |
| ### Installation | |
| TablePro will prompt you to install this plugin automatically when you select the database type. You can also install manually via **Settings > Plugins > Browse**. | |
| ### SHA-256 | |
| - ARM64: \`$ARM64_SHA\` | |
| - x86_64: \`$X86_SHA\`" | |
| # Delete existing release if any, then create | |
| gh release delete "$TAG" --yes 2>/dev/null || true | |
| gh release create "$TAG" \ | |
| --title "$DISPLAY_NAME v$VERSION" \ | |
| --notes "$RELEASE_BODY" \ | |
| build/Plugins/${BUNDLE_NAME}-arm64.zip \ | |
| build/Plugins/${BUNDLE_NAME}-x86_64.zip | |
| # Update plugin registry | |
| if [ -n "${REGISTRY_DEPLOY_KEY:-}" ]; then | |
| ARM64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${BUNDLE_NAME}-arm64.zip" | |
| X86_64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${BUNDLE_NAME}-x86_64.zip" | |
| WORK=$(mktemp -d) | |
| eval "$(ssh-agent -s)" | |
| echo "$REGISTRY_DEPLOY_KEY" | ssh-add - | |
| git clone git@github.com:datlechin/tablepro-plugins.git "$WORK/registry" | |
| cd "$WORK/registry" | |
| git pull --rebase origin main | |
| python3 - \ | |
| "$BUNDLE_ID" "$DISPLAY_NAME" "$VERSION" "$SUMMARY" \ | |
| "$DB_TYPE_IDS" "$ARM64_URL" "$ARM64_SHA" \ | |
| "$X86_64_URL" "$X86_SHA" "$MIN_APP_VERSION" \ | |
| "$ICON" "$HOMEPAGE" \ | |
| <<'PYTHON_SCRIPT' | |
| import json, sys | |
| bundle_id, name, version, summary = sys.argv[1:5] | |
| db_type_ids = json.loads(sys.argv[5]) | |
| arm64_url, arm64_sha = sys.argv[6], sys.argv[7] | |
| x86_64_url, x86_64_sha = sys.argv[8], sys.argv[9] | |
| min_app_version, icon, homepage = sys.argv[10], sys.argv[11], sys.argv[12] | |
| with open("plugins.json", "r") as f: | |
| manifest = json.load(f) | |
| entry = { | |
| "id": bundle_id, "name": name, "version": version, | |
| "summary": summary, | |
| "author": {"name": "TablePro", "url": "https://tablepro.app"}, | |
| "homepage": homepage, "category": "database-driver", | |
| "databaseTypeIds": db_type_ids, | |
| "downloadURL": arm64_url, "sha256": arm64_sha, | |
| "binaries": [ | |
| {"architecture": "arm64", "downloadURL": arm64_url, "sha256": arm64_sha}, | |
| {"architecture": "x86_64", "downloadURL": x86_64_url, "sha256": x86_64_sha} | |
| ], | |
| "minAppVersion": min_app_version, | |
| "minPluginKitVersion": 1, | |
| "iconName": icon, "isVerified": True | |
| } | |
| manifest["plugins"] = [p for p in manifest["plugins"] if p["id"] != bundle_id] | |
| manifest["plugins"].append(entry) | |
| with open("plugins.json", "w") as f: | |
| json.dump(manifest, f, indent=2) | |
| f.write("\n") | |
| PYTHON_SCRIPT | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add plugins.json | |
| git commit -m "Update $DISPLAY_NAME to v$VERSION" | |
| git push | |
| ssh-add -D | |
| eval "$(ssh-agent -k)" | |
| cd - | |
| rm -rf "$WORK" | |
| fi | |
| # Clean plugin build artifacts for next iteration | |
| rm -f build/Plugins/${BUNDLE_NAME}-*.zip build/Plugins/${BUNDLE_NAME}-*.sha256 | |
| echo "✅ $DISPLAY_NAME v$VERSION released" | |
| done | |
| echo "" | |
| echo "========================================" | |
| echo "All plugins processed!" | |
| echo "========================================" |