Skip to content

plugwerk/examples

Plugwerk Examples

Example projects demonstrating plugin development with Plugwerk and the PF4J plugin framework.

Examples

Example Description
plugwerk-java-cli-example Standalone Java CLI application with dynamically loadable command plugins
plugwerk-springboot-thymeleaf-example Spring Boot + Thymeleaf web application with dynamically loadable page plugins

Each example is a self-contained Gradle build. The repository root also provides a Gradle composite build that drives both examples at once. See each example's own README.md for in-depth details.

Prerequisites

  • Java 21 or later
  • Docker and Docker Compose (optional, for running a local Plugwerk server)
  • GitHub Personal Access Token with read:packages scope — only required to resolve Plugwerk SNAPSHOT artifacts from GitHub Packages for Maven (see Resolving Plugwerk dependencies)

Quick start

1. Start a local Plugwerk server (optional)

docker compose up -d

Starts the Plugwerk server (SNAPSHOT image from GHCR) and PostgreSQL. Available at http://localhost:8080 with credentials admin / admin.

The container image ghcr.io/plugwerk/plugwerk-server:snapshot is publicly pullable — no docker login required.

Health check: curl http://localhost:8080/actuator/health{"status":"UP"}. The server has no web frontend under /; use the REST API under /api/v1/... or OpenAPI under /v3/api-docs (auth required).

2. Bootstrap a namespace and an API key

A fresh server has no namespaces, so the very first run needs to create one. Read-only catalog access works anonymously on namespaces with publicCatalog=true; uploads, approvals and access-key management always require an admin JWT.

The Spring example installs and uninstalls plugins through its own controllers, so it expects an X-Api-Key even against a public namespace — the snippet below mints one for both examples to share.

Requires jq (Homebrew: brew install jq).

# 1. Log in as the bootstrap admin and capture a JWT (one-shot, used only for setup)
JWT=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}' | jq -r .accessToken)

# 2. Create the `default` namespace as a public catalog (idempotent: HTTP 409 means it already exists).
#    publicCatalog=true lets `list` / `search` / download work without an API key;
#    set it to false here if you'd rather force key-auth from the start.
curl -sS -o /dev/null -X POST http://localhost:8080/api/v1/namespaces \
  -H "Authorization: Bearer $JWT" \
  -H 'Content-Type: application/json' \
  -d '{"slug":"default","name":"Default","publicCatalog":true,"autoApproveReleases":true}' \
  || true

# 3. Mint a fresh access key — the plain-text value is shown only once
export PLUGWERK_API_KEY=$(curl -s -X POST http://localhost:8080/api/v1/namespaces/default/access-keys \
  -H "Authorization: Bearer $JWT" \
  -H 'Content-Type: application/json' \
  -d '{"name":"local-dev","expiresAt":null}' | jq -r .key)

echo "$PLUGWERK_API_KEY"   # pwk_…

Both examples honour the PLUGWERK_API_KEY environment variable; the CLI also accepts an inline --api-key=… flag. See the per-example README for invocation details.

3. Build both examples (composite build)

From the repository root:

./gradlew build              # Build both examples with tests
./gradlew clean              # Clean both examples
./gradlew check              # Run checks in both examples

Per-example tasks remain reachable via path, e.g.:

./gradlew :plugwerk-springboot-thymeleaf-example:bootRun

4. Build a single example

Each example is also a fully standalone Gradle build:

cd plugwerk-java-cli-example
./gradlew build

Resolving Plugwerk dependencies

Plugwerk ships artifacts from two registries:

Artifact type Registry Auth required
Releases (e.g. 1.0.0) Maven Central No
SNAPSHOTs (e.g. 1.0.0-SNAPSHOT) GitHub Packages for Maven Yes — read:packages token

The examples currently consume SNAPSHOT artifacts during active development, so a token is needed for ./gradlew build in the current setup.

Why is a token needed even though the source repo is public? GitHub Packages for Maven requires authentication for downloads regardless of package visibility — a long-standing limitation that only GHCR (container registry) has fixed. Once Plugwerk switches to release coordinates from Maven Central, no token will be required.

In GitHub Actions (CI)

No configuration needed — the built-in GITHUB_TOKEN already has read:packages scope.

For local development

  1. Create a Classic Personal Access Token at https://github.com/settings/tokens with the read:packages scope.

  2. Add it to ~/.gradle/gradle.properties:

    gpr.user=your-github-username
    gpr.key=ghp_your-personal-access-token

Alternatively, set GITHUB_ACTOR and GITHUB_TOKEN environment variables — the build scripts fall back to those.

See the Plugwerk Development Guide for details.

License

Apache-2.0 — see LICENSE.

About

Example projects demonstrating Plugwerk plugin development for the PF4J ecosystem

Resources

License

Apache-2.0, Unknown licenses found

Licenses found

Apache-2.0
LICENSE
Unknown
license-header.txt

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors