Skip to content

Plugin Architecture Enhancement: ZIP-based Distribution with Hook System #2

@hl4b-hal

Description

@hl4b-hal

Overview

This issue outlines a plan to enhance the GMS plugin architecture with ZIP-based distribution, plugin management in the CMS, and a hook/execution system.

Related Issue (GMS Core Changes): InvertedBit/gms#12


Goals

  1. Plugin Packaging: Ship plugins as .zip files with manifest.json and plugin.so
  2. Plugin Management: Allow uploading plugins to GMS where they are unpacked and registered
  3. Extended Capabilities: Support not just renderable components but also hook-based execution

1. Plugin Packaging Format

ZIP Structure

my-plugin.zip
├── manifest.json          # Plugin metadata
├── plugin.so              # Compiled Go plugin
└── assets/                # Optional static assets
    ├── css/
    ├── js/
    └── images/

manifest.json Schema

{
  "name": "my-plugin",
  "version": "1.0.0",
  "author": "Plugin Author",
  "description": "A GMS plugin",
  "gmsVersion": ">=1.0.0",
  "permissions": ["components", "hooks", "assets"],
  "hooks": [
    {
      "name": "onPageRender",
      "priority": 100
    }
  ],
  "components": [
    {
      "slug": "my-component",
      "name": "My Component",
      "description": "A custom component",
      "properties": [
        {
          "slug": "title",
          "type": "string",
          "required": false,
          "default": "Hello"
        }
      ]
    }
  ],
  "assets": {
    "css": ["assets/css/styles.css"],
    "js": ["assets/js/scripts.js"]
  }
}

2. Automated Build Tool

Create a Makefile or build.go script to automate the plugin packaging process.

Makefile Approach

PLUGIN_NAME=$(shell grep '"name":' manifest.json | cut -d'"' -f4)
VERSION=$(shell grep '"version":' manifest.json | cut -d'"' -f4)
OUTPUT=$(PLUGIN_NAME)-$(VERSION).zip

.PHONY: build test clean checksum sign all

all: test build checksum

test:
	@echo "Running tests..."
	@go test ./... -v
	@if [ $$? -ne 0 ]; then \
		echo "Tests failed! Fix errors before building."; \
		exit 1; \
	fi
	@echo "All tests passed!"

build: manifest.json test
	@echo "Building plugin $(PLUGIN_NAME) v$(VERSION)..."
	@go build -buildmode=plugin -o plugin.so .
	@zip $(OUTPUT) manifest.json plugin.so
	@if [ -d "assets" ]; then zip -r $(OUTPUT) assets/; fi
	@echo "Plugin packaged: $(OUTPUT)"
	@rm -f plugin.so

# Generate SHA-256 checksum (required)
checksum:
	@sha256sum $(OUTPUT) > $(OUTPUT).sha256
	@echo "Checksum created: $(OUTPUT).sha256"

# Generate GPG signature (optional - requires GPG key configured)
sign: checksum
	@gpg --armor --detach-sign $(OUTPUT)
	@echo "Signature created: $(OUTPUT).asc"

clean:
	rm -f $(OUTPUT) $(OUTPUT).sha256 $(OUTPUT).asc plugin.so

Build Script Features

  1. Auto-detect plugin name/version from manifest.json
  2. Run tests first - all tests must pass before build proceeds
  3. Compile to .so using -buildmode=plugin
  4. Create ZIP with manifest.json and plugin.so
  5. Generate SHA-256 checksum - verifies integrity
  6. Generate GPG signature (optional) - verifies authenticity
  7. Include assets if assets/ directory exists
  8. Cleanup temporary files after build

Usage

# Run tests only
make test

# Build plugin with checksum (standard)
make build

# Build + checksum + GPG signature
make sign

# Run tests, build, checksum, and sign
make all

# Clean all build artifacts
make clean

# Output files:
#   my-plugin-1.0.0.zip
#   my-plugin-1.0.0.zip.sha256  (required)
#   my-plugin-1.0.0.asc         (optional, if GPG configured)

Verification

Users can verify plugin integrity:

# Verify checksum
sha256sum -c my-plugin-1.0.0.zip.sha256

# Verify GPG signature (if signed)
gpg --verify my-plugin-1.0.0.zip.asc my-plugin-1.0.0.zip

Integration with CI/CD

# .github/workflows/release.yml
name: Release Plugin

on:
  release:
    types: [created]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.25'
      - name: Run Tests
        run: go test ./... -v

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.25'
      - name: Build Plugin
        run: make build checksum
      - name: Generate Checksum
        run: sha256sum *.zip > checksums.txt
      - name: Upload Release Assets
        uses: softprops/action-gh-release@v2
        with:
          files: |
            *.zip
            *.sha256
            checksums.txt
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CI/CD Features:

  1. Separate test job - Tests run first
  2. Build depends on test - Only builds if tests pass
  3. Checksum generation - SHA-256 checksum file created
  4. Release on tag - Automatically builds on release creation
  5. Artifacts uploaded - ZIP, SHA-256 checksum, and checksums.txt attached

3. Extended Plugin Interface

Current Interface

type Plugin struct {
    Name        string
    Author      string
    Version     string
    Description string
    Components  map[string]Component
}

Proposed Extended Interface

type Plugin struct {
    Name        string
    Author      string
    Version     string
    Description string
    Components  map[string]Component
    
    // New fields
    Hooks       map[string]HookHandler
    Permissions []string
}

// HookHandler is a function that handles a hook event
type HookHandler func(ctx context.Context, args map[string]interface{}) error

// GetPluginInfo returns plugin metadata
func GetPluginInfo() PluginInfo

// Initialize is called when plugin is loaded
func Initialize(registry HookRegistry) error

// Shutdown is called when plugin is unloaded
func Shutdown() error

4. Files to Modify

gms-plugins/

  • manifest.go - New file for manifest parsing
  • components/model.go - Add properties to Component
  • plugins/general.go - Add hook registration
  • Makefile - Automated build and packaging script
  • README.md - Update documentation

See Also (GMS Core)


Contributors: @hl4b-hal

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions