Skip to content

Commit f99d97f

Browse files
committed
ci: support batch plugin builds in single workflow run
1 parent 8f15ebf commit f99d97f

File tree

1 file changed

+164
-197
lines changed

1 file changed

+164
-197
lines changed

.github/workflows/build-plugin.yml

Lines changed: 164 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ on:
55
tags: ["plugin-*-v*"]
66
workflow_dispatch:
77
inputs:
8-
tag:
9-
description: "Plugin tag to build (e.g., plugin-oracle-v1.0.1)"
8+
tags:
9+
description: "Plugin tags, comma-separated (e.g., plugin-oracle-v1.0.1,plugin-sqlite-v1.0.1)"
1010
required: true
1111
type: string
1212

@@ -20,75 +20,9 @@ jobs:
2020
build-plugin:
2121
name: Build Plugin
2222
runs-on: self-hosted
23-
timeout-minutes: 30
23+
timeout-minutes: 60
2424

2525
steps:
26-
- name: Extract plugin info from tag
27-
id: plugin-info
28-
run: |
29-
TAG="${{ inputs.tag || github.ref_name }}"
30-
# Tag format: plugin-<name>-v<version>
31-
# e.g., plugin-oracle-v1.0.0 -> OracleDriverPlugin
32-
PLUGIN_NAME=$(echo "$TAG" | sed -E 's/^plugin-([a-z]+)-v.*$/\1/')
33-
VERSION=$(echo "$TAG" | sed -E 's/^plugin-[a-z]+-v(.*)$/\1/')
34-
35-
# Map short name to Xcode target and registry metadata
36-
case "$PLUGIN_NAME" in
37-
oracle)
38-
TARGET="OracleDriver"
39-
BUNDLE_ID="com.TablePro.OracleDriver"
40-
DISPLAY_NAME="Oracle Driver"
41-
SUMMARY="Oracle Database 12c+ driver via OracleNIO"
42-
DB_TYPE_IDS='["Oracle"]'
43-
ICON="server.rack"
44-
BUNDLE_NAME="OracleDriver"
45-
HOMEPAGE="https://tablepro.app/databases/oracle"
46-
;;
47-
clickhouse)
48-
TARGET="ClickHouseDriver"
49-
BUNDLE_ID="com.TablePro.ClickHouseDriver"
50-
DISPLAY_NAME="ClickHouse Driver"
51-
SUMMARY="ClickHouse OLAP database driver via HTTP interface"
52-
DB_TYPE_IDS='["ClickHouse"]'
53-
ICON="chart.bar.xaxis"
54-
BUNDLE_NAME="ClickHouseDriver"
55-
HOMEPAGE="https://tablepro.app/databases/clickhouse"
56-
;;
57-
sqlite)
58-
TARGET="SQLiteDriver"
59-
BUNDLE_ID="com.TablePro.SQLiteDriver"
60-
DISPLAY_NAME="SQLite Driver"
61-
SUMMARY="SQLite embedded database driver"
62-
DB_TYPE_IDS='["SQLite"]'
63-
ICON="internaldrive"
64-
BUNDLE_NAME="SQLiteDriver"
65-
HOMEPAGE="https://tablepro.app"
66-
;;
67-
duckdb)
68-
TARGET="DuckDBDriver"
69-
BUNDLE_ID="com.TablePro.DuckDBDriver"
70-
DISPLAY_NAME="DuckDB Driver"
71-
SUMMARY="DuckDB analytical database driver"
72-
DB_TYPE_IDS='["DuckDB"]'
73-
ICON="bird"
74-
BUNDLE_NAME="DuckDBDriver"
75-
HOMEPAGE="https://tablepro.app"
76-
;;
77-
*) echo "Unknown plugin: $PLUGIN_NAME"; exit 1 ;;
78-
esac
79-
80-
echo "target=$TARGET" >> "$GITHUB_OUTPUT"
81-
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
82-
echo "plugin_name=$PLUGIN_NAME" >> "$GITHUB_OUTPUT"
83-
echo "bundle_id=$BUNDLE_ID" >> "$GITHUB_OUTPUT"
84-
echo "display_name=$DISPLAY_NAME" >> "$GITHUB_OUTPUT"
85-
echo "summary=$SUMMARY" >> "$GITHUB_OUTPUT"
86-
echo "db_type_ids=$DB_TYPE_IDS" >> "$GITHUB_OUTPUT"
87-
echo "icon=$ICON" >> "$GITHUB_OUTPUT"
88-
echo "bundle_name=$BUNDLE_NAME" >> "$GITHUB_OUTPUT"
89-
echo "homepage=$HOMEPAGE" >> "$GITHUB_OUTPUT"
90-
echo "Building $TARGET v$VERSION"
91-
9226
- name: Install Git LFS
9327
run: brew list git-lfs &>/dev/null || brew install git-lfs; git lfs install
9428

@@ -100,142 +34,175 @@ jobs:
10034
- name: Pull LFS files
10135
run: git lfs pull
10236

103-
- name: Build plugin (ARM64)
104-
run: ./scripts/build-plugin.sh "${{ steps.plugin-info.outputs.target }}" arm64
105-
106-
- name: Build plugin (x86_64)
107-
run: ./scripts/build-plugin.sh "${{ steps.plugin-info.outputs.target }}" x86_64
108-
109-
- name: Capture SHA-256 hashes
110-
# Hashes are captured before notarize intentionally: notarytool does not
111-
# modify the ZIP on disk, and stapling applies to app bundles, not ZIPs.
112-
id: sha256
113-
run: |
114-
BUNDLE_NAME="${{ steps.plugin-info.outputs.bundle_name }}"
115-
ARM64_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-arm64.zip.sha256")
116-
X86_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-x86_64.zip.sha256")
117-
echo "arm64=$ARM64_SHA" >> "$GITHUB_OUTPUT"
118-
echo "x86_64=$X86_SHA" >> "$GITHUB_OUTPUT"
119-
120-
- name: Notarize
121-
if: vars.NOTARIZE_PLUGINS == 'true'
122-
run: |
123-
for zip in build/Plugins/*.zip; do
124-
xcrun notarytool submit "$zip" \
125-
--apple-id "$APPLE_ID" \
126-
--team-id "D7HJ5TFYCU" \
127-
--keychain-profile "notarytool-profile" \
128-
--wait
129-
done
130-
131-
- name: Create GitHub Release
132-
uses: softprops/action-gh-release@v2
133-
with:
134-
name: "${{ steps.plugin-info.outputs.display_name }} v${{ steps.plugin-info.outputs.version }}"
135-
body: |
136-
## ${{ steps.plugin-info.outputs.display_name }} v${{ steps.plugin-info.outputs.version }}
137-
138-
Plugin release for TablePro.
139-
140-
### Installation
141-
TablePro will prompt you to install this plugin automatically when you select the database type. You can also install manually via **Settings > Plugins > Browse**.
142-
143-
### SHA-256
144-
- ARM64: `${{ steps.sha256.outputs.arm64 }}`
145-
- x86_64: `${{ steps.sha256.outputs.x86_64 }}`
146-
files: build/Plugins/*.zip
147-
draft: false
148-
prerelease: false
149-
150-
- name: Update plugin registry
37+
- name: Build and release plugins
15138
env:
15239
REGISTRY_DEPLOY_KEY: ${{ secrets.REGISTRY_DEPLOY_KEY }}
40+
GH_TOKEN: ${{ github.token }}
15341
run: |
154-
TAG="${{ inputs.tag || github.ref_name }}"
155-
156-
ARM64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${{ steps.plugin-info.outputs.bundle_name }}-arm64.zip"
157-
X86_64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${{ steps.plugin-info.outputs.bundle_name }}-x86_64.zip"
158-
159-
# Get current app version as minAppVersion
42+
# Build tag list: from input (comma-separated) or from push event (single tag)
43+
if [ -n "${{ inputs.tags }}" ]; then
44+
IFS=',' read -ra TAGS <<< "${{ inputs.tags }}"
45+
else
46+
TAGS=("${{ github.ref_name }}")
47+
fi
48+
49+
# Get current app version for minAppVersion
16050
MIN_APP_VERSION=$(sed -n 's/.*MARKETING_VERSION = \(.*\);/\1/p' \
16151
TablePro.xcodeproj/project.pbxproj | head -1 | tr -d ' ')
16252
163-
# Clone the registry repo
164-
WORK=$(mktemp -d)
165-
eval "$(ssh-agent -s)"
166-
echo "$REGISTRY_DEPLOY_KEY" | ssh-add -
167-
git clone git@github.com:datlechin/tablepro-plugins.git "$WORK/registry"
168-
cd "$WORK/registry"
169-
170-
# Update plugins.json via Python
171-
python3 - \
172-
"${{ steps.plugin-info.outputs.bundle_id }}" \
173-
"${{ steps.plugin-info.outputs.display_name }}" \
174-
"${{ steps.plugin-info.outputs.version }}" \
175-
"${{ steps.plugin-info.outputs.summary }}" \
176-
'${{ steps.plugin-info.outputs.db_type_ids }}' \
177-
"$ARM64_URL" \
178-
"${{ steps.sha256.outputs.arm64 }}" \
179-
"$X86_64_URL" \
180-
"${{ steps.sha256.outputs.x86_64 }}" \
181-
"$MIN_APP_VERSION" \
182-
"${{ steps.plugin-info.outputs.icon }}" \
183-
"${{ steps.plugin-info.outputs.homepage }}" \
184-
<<'PYTHON_SCRIPT'
185-
import json, sys
186-
187-
bundle_id = sys.argv[1]
188-
name = sys.argv[2]
189-
version = sys.argv[3]
190-
summary = sys.argv[4]
191-
db_type_ids = json.loads(sys.argv[5])
192-
arm64_url = sys.argv[6]
193-
arm64_sha = sys.argv[7]
194-
x86_64_url = sys.argv[8]
195-
x86_64_sha = sys.argv[9]
196-
min_app_version = sys.argv[10]
197-
icon = sys.argv[11]
198-
homepage = sys.argv[12]
199-
200-
with open("plugins.json", "r") as f:
201-
manifest = json.load(f)
202-
203-
entry = {
204-
"id": bundle_id,
205-
"name": name,
206-
"version": version,
207-
"summary": summary,
208-
"author": {"name": "TablePro", "url": "https://tablepro.app"},
209-
"homepage": homepage,
210-
"category": "database-driver",
211-
"databaseTypeIds": db_type_ids,
212-
"downloadURL": arm64_url,
213-
"sha256": arm64_sha,
214-
"binaries": [
215-
{"architecture": "arm64", "downloadURL": arm64_url, "sha256": arm64_sha},
216-
{"architecture": "x86_64", "downloadURL": x86_64_url, "sha256": x86_64_sha}
217-
],
218-
"minAppVersion": min_app_version,
219-
"minPluginKitVersion": 1,
220-
"iconName": icon,
221-
"isVerified": True
53+
resolve_plugin_info() {
54+
local plugin_name=$1
55+
case "$plugin_name" in
56+
oracle)
57+
TARGET="OracleDriver"; BUNDLE_ID="com.TablePro.OracleDriver"
58+
DISPLAY_NAME="Oracle Driver"; SUMMARY="Oracle Database 12c+ driver via OracleNIO"
59+
DB_TYPE_IDS='["Oracle"]'; ICON="server.rack"; BUNDLE_NAME="OracleDriver"
60+
HOMEPAGE="https://tablepro.app/databases/oracle" ;;
61+
clickhouse)
62+
TARGET="ClickHouseDriver"; BUNDLE_ID="com.TablePro.ClickHouseDriver"
63+
DISPLAY_NAME="ClickHouse Driver"; SUMMARY="ClickHouse OLAP database driver via HTTP interface"
64+
DB_TYPE_IDS='["ClickHouse"]'; ICON="chart.bar.xaxis"; BUNDLE_NAME="ClickHouseDriver"
65+
HOMEPAGE="https://tablepro.app/databases/clickhouse" ;;
66+
sqlite)
67+
TARGET="SQLiteDriver"; BUNDLE_ID="com.TablePro.SQLiteDriver"
68+
DISPLAY_NAME="SQLite Driver"; SUMMARY="SQLite embedded database driver"
69+
DB_TYPE_IDS='["SQLite"]'; ICON="internaldrive"; BUNDLE_NAME="SQLiteDriver"
70+
HOMEPAGE="https://tablepro.app" ;;
71+
duckdb)
72+
TARGET="DuckDBDriver"; BUNDLE_ID="com.TablePro.DuckDBDriver"
73+
DISPLAY_NAME="DuckDB Driver"; SUMMARY="DuckDB analytical database driver"
74+
DB_TYPE_IDS='["DuckDB"]'; ICON="bird"; BUNDLE_NAME="DuckDBDriver"
75+
HOMEPAGE="https://tablepro.app" ;;
76+
*) echo "Unknown plugin: $plugin_name"; return 1 ;;
77+
esac
22278
}
22379
224-
manifest["plugins"] = [p for p in manifest["plugins"] if p["id"] != bundle_id]
225-
manifest["plugins"].append(entry)
226-
227-
with open("plugins.json", "w") as f:
228-
json.dump(manifest, f, indent=2)
229-
f.write("\n")
80+
for TAG in "${TAGS[@]}"; do
81+
TAG=$(echo "$TAG" | xargs) # trim whitespace
82+
echo ""
83+
echo "========================================"
84+
echo "Processing: $TAG"
85+
echo "========================================"
86+
87+
PLUGIN_NAME=$(echo "$TAG" | sed -E 's/^plugin-([a-z]+)-v.*$/\1/')
88+
VERSION=$(echo "$TAG" | sed -E 's/^plugin-[a-z]+-v(.*)$/\1/')
89+
90+
resolve_plugin_info "$PLUGIN_NAME" || continue
91+
92+
echo "Building $TARGET v$VERSION"
93+
94+
# Build both architectures
95+
./scripts/build-plugin.sh "$TARGET" arm64
96+
./scripts/build-plugin.sh "$TARGET" x86_64
97+
98+
# Capture SHA-256
99+
ARM64_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-arm64.zip.sha256")
100+
X86_SHA=$(cat "build/Plugins/${BUNDLE_NAME}-x86_64.zip.sha256")
101+
102+
# Notarize if enabled
103+
if [ "${NOTARIZE_PLUGINS:-}" = "true" ]; then
104+
for zip in build/Plugins/${BUNDLE_NAME}-*.zip; do
105+
xcrun notarytool submit "$zip" \
106+
--apple-id "$APPLE_ID" \
107+
--team-id "D7HJ5TFYCU" \
108+
--keychain-profile "notarytool-profile" \
109+
--wait
110+
done
111+
fi
112+
113+
# Create GitHub Release
114+
RELEASE_BODY="## $DISPLAY_NAME v$VERSION
115+
116+
Plugin release for TablePro.
117+
118+
### Installation
119+
TablePro will prompt you to install this plugin automatically when you select the database type. You can also install manually via **Settings > Plugins > Browse**.
120+
121+
### SHA-256
122+
- ARM64: \`$ARM64_SHA\`
123+
- x86_64: \`$X86_SHA\`"
124+
125+
# Delete existing release if any, then create
126+
gh release delete "$TAG" --yes 2>/dev/null || true
127+
gh release create "$TAG" \
128+
--title "$DISPLAY_NAME v$VERSION" \
129+
--notes "$RELEASE_BODY" \
130+
build/Plugins/${BUNDLE_NAME}-arm64.zip \
131+
build/Plugins/${BUNDLE_NAME}-x86_64.zip
132+
133+
# Update plugin registry
134+
if [ -n "${REGISTRY_DEPLOY_KEY:-}" ]; then
135+
ARM64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${BUNDLE_NAME}-arm64.zip"
136+
X86_64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${BUNDLE_NAME}-x86_64.zip"
137+
138+
WORK=$(mktemp -d)
139+
eval "$(ssh-agent -s)"
140+
echo "$REGISTRY_DEPLOY_KEY" | ssh-add -
141+
142+
git clone git@github.com:datlechin/tablepro-plugins.git "$WORK/registry"
143+
cd "$WORK/registry"
144+
git pull --rebase origin main
145+
146+
python3 - \
147+
"$BUNDLE_ID" "$DISPLAY_NAME" "$VERSION" "$SUMMARY" \
148+
"$DB_TYPE_IDS" "$ARM64_URL" "$ARM64_SHA" \
149+
"$X86_64_URL" "$X86_SHA" "$MIN_APP_VERSION" \
150+
"$ICON" "$HOMEPAGE" \
151+
<<'PYTHON_SCRIPT'
152+
import json, sys
153+
154+
bundle_id, name, version, summary = sys.argv[1:5]
155+
db_type_ids = json.loads(sys.argv[5])
156+
arm64_url, arm64_sha = sys.argv[6], sys.argv[7]
157+
x86_64_url, x86_64_sha = sys.argv[8], sys.argv[9]
158+
min_app_version, icon, homepage = sys.argv[10], sys.argv[11], sys.argv[12]
159+
160+
with open("plugins.json", "r") as f:
161+
manifest = json.load(f)
162+
163+
entry = {
164+
"id": bundle_id, "name": name, "version": version,
165+
"summary": summary,
166+
"author": {"name": "TablePro", "url": "https://tablepro.app"},
167+
"homepage": homepage, "category": "database-driver",
168+
"databaseTypeIds": db_type_ids,
169+
"downloadURL": arm64_url, "sha256": arm64_sha,
170+
"binaries": [
171+
{"architecture": "arm64", "downloadURL": arm64_url, "sha256": arm64_sha},
172+
{"architecture": "x86_64", "downloadURL": x86_64_url, "sha256": x86_64_sha}
173+
],
174+
"minAppVersion": min_app_version,
175+
"minPluginKitVersion": 1,
176+
"iconName": icon, "isVerified": True
177+
}
178+
179+
manifest["plugins"] = [p for p in manifest["plugins"] if p["id"] != bundle_id]
180+
manifest["plugins"].append(entry)
181+
182+
with open("plugins.json", "w") as f:
183+
json.dump(manifest, f, indent=2)
184+
f.write("\n")
230185
PYTHON_SCRIPT
231186
232-
git config user.name "github-actions[bot]"
233-
git config user.email "github-actions[bot]@users.noreply.github.com"
234-
git add plugins.json
235-
git commit -m "Update ${{ steps.plugin-info.outputs.display_name }} to v${{ steps.plugin-info.outputs.version }}"
236-
git push
187+
git config user.name "github-actions[bot]"
188+
git config user.email "github-actions[bot]@users.noreply.github.com"
189+
git add plugins.json
190+
git commit -m "Update $DISPLAY_NAME to v$VERSION"
191+
git push
192+
193+
ssh-add -D
194+
eval "$(ssh-agent -k)"
195+
cd -
196+
rm -rf "$WORK"
197+
fi
198+
199+
# Clean plugin build artifacts for next iteration
200+
rm -f build/Plugins/${BUNDLE_NAME}-*.zip build/Plugins/${BUNDLE_NAME}-*.sha256
201+
202+
echo "✅ $DISPLAY_NAME v$VERSION released"
203+
done
237204
238-
# Cleanup
239-
ssh-add -D
240-
eval "$(ssh-agent -k)"
241-
rm -rf "$WORK"
205+
echo ""
206+
echo "========================================"
207+
echo "All plugins processed!"
208+
echo "========================================"

0 commit comments

Comments
 (0)