From befd7b0a4ede85437c8d8586aad57b810b314356 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Mon, 1 Jun 2026 14:10:07 -0400 Subject: [PATCH 1/3] chore: apply plugin version discipline --- .github/workflows/release.yml | 3 + .github/workflows/sync-plugin-version.yml | 59 -------- plugin.json | 176 +++++++++++----------- 3 files changed, 91 insertions(+), 147 deletions(-) delete mode 100644 .github/workflows/sync-plugin-version.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e150b7..44e3dba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,6 +45,9 @@ jobs: exit 0 fi "${{ runner.temp }}/wfctl-bin/wfctl" plugin verify-capabilities --binary "$BIN" . + - name: Verify shipped plugin.json carries tag (post-build) + run: | + "${{ runner.temp }}/wfctl-bin/wfctl" plugin validate-contract --for-publish --tag ${{ github.ref_name }} --release-dir . . - name: Publish GitHub release uses: actions/github-script@v7 with: diff --git a/.github/workflows/sync-plugin-version.yml b/.github/workflows/sync-plugin-version.yml deleted file mode 100644 index f74f8a9..0000000 --- a/.github/workflows/sync-plugin-version.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Sync plugin.json version -on: - push: - tags: ['v*'] -permissions: - contents: write - pull-requests: write -jobs: - sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: main - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - name: Compute target version from tag - id: ver - run: | - TAG="${GITHUB_REF_NAME}" - VERSION="${TAG#v}" - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "tag=$TAG" >> $GITHUB_OUTPUT - - name: Update plugin.json - run: | - if [ ! -f plugin.json ]; then echo "no plugin.json; skipping"; exit 0; fi - CURRENT=$(python3 -c "import json; print(json.load(open('plugin.json')).get('version',''))") - TARGET="${{ steps.ver.outputs.version }}" - if [ "$CURRENT" = "$TARGET" ]; then - echo "plugin.json already at $TARGET; no action" - exit 0 - fi - python3 -c " - import json - p = json.load(open('plugin.json')) - p['version'] = '$TARGET' - json.dump(p, open('plugin.json', 'w'), indent=2) - open('plugin.json', 'a').write('\n') - " - - name: Open sync PR if plugin.json changed - run: | - if git diff --quiet plugin.json; then - echo "no changes" - exit 0 - fi - BRANCH="chore/sync-plugin-version-${{ steps.ver.outputs.tag }}" - git config user.email "github-actions[bot]@users.noreply.github.com" - git config user.name "github-actions[bot]" - git checkout -b "$BRANCH" - git add plugin.json - git commit -m "chore: sync plugin.json version to ${{ steps.ver.outputs.tag }}" - git push origin "$BRANCH" - gh pr create \ - --base main \ - --head "$BRANCH" \ - --title "chore: sync plugin.json version to ${{ steps.ver.outputs.tag }}" \ - --body "Triggered by release ${{ steps.ver.outputs.tag }}. Auto-sync to prevent drift. Closes workflow-registry#37." - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/plugin.json b/plugin.json index 1c97a6d..d4cbd0e 100644 --- a/plugin.json +++ b/plugin.json @@ -1,96 +1,96 @@ { - "name": "workflow-plugin-websocket", - "version": "0.5.6", - "author": "GoCodeAlone", - "description": "General-purpose WebSocket support for workflow applications", - "type": "external", - "tier": "community", - "license": "MIT", - "repository": "https://github.com/GoCodeAlone/workflow-plugin-websocket", - "homepage": "https://github.com/GoCodeAlone/workflow-plugin-websocket", - "minEngineVersion": "0.51.7", - "keywords": [ - "websocket", - "ws", - "realtime", - "streaming" + "name": "workflow-plugin-websocket", + "version": "0.0.0", + "author": "GoCodeAlone", + "description": "General-purpose WebSocket support for workflow applications", + "type": "external", + "tier": "community", + "license": "MIT", + "repository": "https://github.com/GoCodeAlone/workflow-plugin-websocket", + "homepage": "https://github.com/GoCodeAlone/workflow-plugin-websocket", + "minEngineVersion": "0.51.7", + "keywords": [ + "websocket", + "ws", + "realtime", + "streaming" + ], + "capabilities": { + "moduleTypes": [ + "ws.server" ], - "capabilities": { - "moduleTypes": [ - "ws.server" - ], - "stepTypes": [ - "step.ws_send", - "step.ws_close" - ], - "triggerTypes": [ - "websocket" - ] + "stepTypes": [ + "step.ws_send", + "step.ws_close" + ], + "triggerTypes": [ + "websocket" + ] + }, + "stepSchemas": [ + { + "type": "step.ws_send", + "plugin": "workflow-plugin-websocket", + "description": "Send a text message to a WebSocket connection by connection ID.", + "configFields": [ + { + "key": "connectionId", + "label": "Connection ID", + "type": "string", + "description": "The unique identifier of the WebSocket connection to send the message to.", + "required": true, + "placeholder": "{{ .connectionId }}" + }, + { + "key": "message", + "label": "Message", + "type": "string", + "description": "The text message to send to the WebSocket connection.", + "required": true, + "placeholder": "Hello, world!" + } + ], + "outputs": [ + { + "key": "sent", + "type": "boolean", + "description": "Whether the message was successfully sent to the connection." + }, + { + "key": "error", + "type": "string", + "description": "Error message when the send failed (e.g. ws.server not initialized, missing connectionId).", + "optional": true + } + ] }, - "stepSchemas": [ + { + "type": "step.ws_close", + "plugin": "workflow-plugin-websocket", + "description": "Close a WebSocket connection by connection ID.", + "configFields": [ { - "type": "step.ws_send", - "plugin": "workflow-plugin-websocket", - "description": "Send a text message to a WebSocket connection by connection ID.", - "configFields": [ - { - "key": "connectionId", - "label": "Connection ID", - "type": "string", - "description": "The unique identifier of the WebSocket connection to send the message to.", - "required": true, - "placeholder": "{{ .connectionId }}" - }, - { - "key": "message", - "label": "Message", - "type": "string", - "description": "The text message to send to the WebSocket connection.", - "required": true, - "placeholder": "Hello, world!" - } - ], - "outputs": [ - { - "key": "sent", - "type": "boolean", - "description": "Whether the message was successfully sent to the connection." - }, - { - "key": "error", - "type": "string", - "description": "Error message when the send failed (e.g. ws.server not initialized, missing connectionId).", - "optional": true - } - ] + "key": "connectionId", + "label": "Connection ID", + "type": "string", + "description": "The unique identifier of the WebSocket connection to close.", + "required": true, + "placeholder": "{{ .connectionId }}" + } + ], + "outputs": [ + { + "key": "closed", + "type": "boolean", + "description": "Whether the connection was found and closed." }, { - "type": "step.ws_close", - "plugin": "workflow-plugin-websocket", - "description": "Close a WebSocket connection by connection ID.", - "configFields": [ - { - "key": "connectionId", - "label": "Connection ID", - "type": "string", - "description": "The unique identifier of the WebSocket connection to close.", - "required": true, - "placeholder": "{{ .connectionId }}" - } - ], - "outputs": [ - { - "key": "closed", - "type": "boolean", - "description": "Whether the connection was found and closed." - }, - { - "key": "error", - "type": "string", - "description": "Error message when the close failed (e.g. ws.server not initialized).", - "optional": true - } - ] + "key": "error", + "type": "string", + "description": "Error message when the close failed (e.g. ws.server not initialized).", + "optional": true } - ] + ] + } + ] } From 6ba01807b927c27b67444828d707b62182e7ff67 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Mon, 1 Jun 2026 14:10:39 -0400 Subject: [PATCH 2/3] chore: preserve manifest formatting --- plugin.json | 176 ++++++++++++++++++++++++++-------------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/plugin.json b/plugin.json index d4cbd0e..a6534d9 100644 --- a/plugin.json +++ b/plugin.json @@ -1,96 +1,96 @@ { - "name": "workflow-plugin-websocket", - "version": "0.0.0", - "author": "GoCodeAlone", - "description": "General-purpose WebSocket support for workflow applications", - "type": "external", - "tier": "community", - "license": "MIT", - "repository": "https://github.com/GoCodeAlone/workflow-plugin-websocket", - "homepage": "https://github.com/GoCodeAlone/workflow-plugin-websocket", - "minEngineVersion": "0.51.7", - "keywords": [ - "websocket", - "ws", - "realtime", - "streaming" - ], - "capabilities": { - "moduleTypes": [ - "ws.server" + "name": "workflow-plugin-websocket", + "version": "0.0.0", + "author": "GoCodeAlone", + "description": "General-purpose WebSocket support for workflow applications", + "type": "external", + "tier": "community", + "license": "MIT", + "repository": "https://github.com/GoCodeAlone/workflow-plugin-websocket", + "homepage": "https://github.com/GoCodeAlone/workflow-plugin-websocket", + "minEngineVersion": "0.51.7", + "keywords": [ + "websocket", + "ws", + "realtime", + "streaming" ], - "stepTypes": [ - "step.ws_send", - "step.ws_close" - ], - "triggerTypes": [ - "websocket" - ] - }, - "stepSchemas": [ - { - "type": "step.ws_send", - "plugin": "workflow-plugin-websocket", - "description": "Send a text message to a WebSocket connection by connection ID.", - "configFields": [ - { - "key": "connectionId", - "label": "Connection ID", - "type": "string", - "description": "The unique identifier of the WebSocket connection to send the message to.", - "required": true, - "placeholder": "{{ .connectionId }}" - }, - { - "key": "message", - "label": "Message", - "type": "string", - "description": "The text message to send to the WebSocket connection.", - "required": true, - "placeholder": "Hello, world!" - } - ], - "outputs": [ - { - "key": "sent", - "type": "boolean", - "description": "Whether the message was successfully sent to the connection." - }, - { - "key": "error", - "type": "string", - "description": "Error message when the send failed (e.g. ws.server not initialized, missing connectionId).", - "optional": true - } - ] + "capabilities": { + "moduleTypes": [ + "ws.server" + ], + "stepTypes": [ + "step.ws_send", + "step.ws_close" + ], + "triggerTypes": [ + "websocket" + ] }, - { - "type": "step.ws_close", - "plugin": "workflow-plugin-websocket", - "description": "Close a WebSocket connection by connection ID.", - "configFields": [ + "stepSchemas": [ { - "key": "connectionId", - "label": "Connection ID", - "type": "string", - "description": "The unique identifier of the WebSocket connection to close.", - "required": true, - "placeholder": "{{ .connectionId }}" - } - ], - "outputs": [ - { - "key": "closed", - "type": "boolean", - "description": "Whether the connection was found and closed." + "type": "step.ws_send", + "plugin": "workflow-plugin-websocket", + "description": "Send a text message to a WebSocket connection by connection ID.", + "configFields": [ + { + "key": "connectionId", + "label": "Connection ID", + "type": "string", + "description": "The unique identifier of the WebSocket connection to send the message to.", + "required": true, + "placeholder": "{{ .connectionId }}" + }, + { + "key": "message", + "label": "Message", + "type": "string", + "description": "The text message to send to the WebSocket connection.", + "required": true, + "placeholder": "Hello, world!" + } + ], + "outputs": [ + { + "key": "sent", + "type": "boolean", + "description": "Whether the message was successfully sent to the connection." + }, + { + "key": "error", + "type": "string", + "description": "Error message when the send failed (e.g. ws.server not initialized, missing connectionId).", + "optional": true + } + ] }, { - "key": "error", - "type": "string", - "description": "Error message when the close failed (e.g. ws.server not initialized).", - "optional": true + "type": "step.ws_close", + "plugin": "workflow-plugin-websocket", + "description": "Close a WebSocket connection by connection ID.", + "configFields": [ + { + "key": "connectionId", + "label": "Connection ID", + "type": "string", + "description": "The unique identifier of the WebSocket connection to close.", + "required": true, + "placeholder": "{{ .connectionId }}" + } + ], + "outputs": [ + { + "key": "closed", + "type": "boolean", + "description": "Whether the connection was found and closed." + }, + { + "key": "error", + "type": "string", + "description": "Error message when the close failed (e.g. ws.server not initialized).", + "optional": true + } + ] } - ] - } - ] + ] } From e22e099ca429f9cfbaaf78320d69c68dc09fa568 Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Mon, 1 Jun 2026 14:17:46 -0400 Subject: [PATCH 3/3] fix: harden release validation quoting --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 44e3dba..ab53151 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: "https://github.com/GoCodeAlone/workflow/releases/download/v0.63.2/wfctl-linux-amd64" chmod +x "${RUNNER_TEMP}/wfctl-bin/wfctl" - name: Validate plugin contract for publish (pre-build) - run: "${{ runner.temp }}/wfctl-bin/wfctl plugin validate-contract --for-publish --tag ${{ github.ref_name }} ." + run: "${{ runner.temp }}/wfctl-bin/wfctl plugin validate-contract --for-publish --tag "${{ github.ref_name }}" ." - uses: goreleaser/goreleaser-action@v7 with: version: '~> v2' @@ -47,7 +47,7 @@ jobs: "${{ runner.temp }}/wfctl-bin/wfctl" plugin verify-capabilities --binary "$BIN" . - name: Verify shipped plugin.json carries tag (post-build) run: | - "${{ runner.temp }}/wfctl-bin/wfctl" plugin validate-contract --for-publish --tag ${{ github.ref_name }} --release-dir . . + "${{ runner.temp }}/wfctl-bin/wfctl" plugin validate-contract --for-publish --tag "${{ github.ref_name }}" --release-dir . . - name: Publish GitHub release uses: actions/github-script@v7 with: