This GitHub Actions workflow automatically publishes your WordPress plugin to a FAIR (Federated Asset Integrity Registry) repository, implementing the FAIR Protocol for decentralized package management.
Follow these steps in order to publish your plugin to the FAIR repository:
Copy all the workflow files to your repository:
# Your repository structure should look like this:
.github/
├── scripts/
│ └── fair/
│ ├── create-did.php
│ ├── generate-keys-local.php
│ ├── generate-metadata.php
│ ├── manage-keys.php
│ ├── sign-artifact.php
│ └── update-did-service.php
└── workflows/
├── fair-publish.yml
└── release.yml # (you should already have this)Commit and push these files:
git add .github/
git commit -m "Add FAIR publishing workflow"
git pushImportant: For security, keys are generated on YOUR machine, not on GitHub.
# Make sure you're in your plugin directory
cd path/to/your-plugin
# Run the key generator
php .github/scripts/fair/generate-keys-local.phpThe script will display 4 keys. Keep this terminal window open - you'll need to copy these keys in the next step.
-
Go to your GitHub repository
-
Click on Settings (top menu)
-
In the left sidebar, click Secrets and variables → Actions
-
Click the New repository secret button
-
Add each of these 4 secrets (copy the values from your terminal):
Secret Name Copy from terminal FAIR_ROTATION_KEY_PRIVATEFirst key displayed FAIR_ROTATION_KEY_PUBLICSecond key displayed FAIR_VERIFICATION_KEY_PRIVATEThird key displayed FAIR_VERIFICATION_KEY_PUBLICFourth key displayed -
After adding all 4 secrets, you can close the terminal (or clear the history for security)
The FAIR publish workflow triggers automatically after the release workflow completes.
Option A: Create a release via tag (Recommended)
# Create and push a new version tag
git tag v1.0.0
git push origin v1.0.0Option B: Create a release manually
- Go to your repository on GitHub
- Click Releases → Draft a new release
- Click Choose a tag → Type your version (e.g.,
v1.0.0) → Create new tag - Fill in the release title and description
- Click Publish release
After the release workflow completes:
-
The "Publish to FAIR Repository" workflow will automatically start
-
Go to the Actions tab to monitor progress
-
The workflow will:
- Create a DID for your plugin (first time only)
- Download the release asset
- Sign the package with your verification key
- Generate FAIR metadata
- Upload
fair-metadata.jsonto the release - Register with the PLC directory
-
Once complete, check the release - you'll see
fair-metadata.jsonattached
🎉 Congratulations! Your plugin is now published to the FAIR repository!
Important: After your FIRST successful publish, you must save the generated DID as a repository variable.
- Go to the Actions tab in your repository
- Click on the latest "Publish to FAIR Repository" workflow run
- Check the Summary section at the top - your DID will be displayed in a box
- Copy the DID value (format:
did:plc:...) - Add it as a repository variable (not a secret):
- Go to: Settings → Secrets and variables → Actions
- Click the "Variables" tab
- Click "New repository variable"
- Name:
FAIR_DID - Value: (paste the DID, e.g.,
did:plc:abc123xyz...) - Click "Add variable"
Why use Variables instead of Secrets? DIDs contain special characters (like :) that aren't allowed in secrets. Variables are perfect for non-sensitive identifiers like DIDs.
Why save it? This DID identifies your plugin in the FAIR protocol. Saving it as a variable allows future releases to use the same identity instead of creating a new DID each time.
This step is only needed once. Future publishes will automatically use this stored DID.
When you create a release, here's the full flow:
-
Release Workflow (
release.yml) runs:- Builds plugin ZIP
- Creates GitHub release
- Uploads ZIP as release asset
-
FAIR Publish Workflow (
fair-publish.yml) runs automatically:- Validates cryptographic keys exist
- Creates or uses existing DID
- Downloads the release ZIP
- Signs the ZIP with verification key
- Generates FAIR metadata
- Uploads metadata to release
-
Your plugin is now available via FAIR protocol!
The workflow runs in two scenarios:
- Automatically after release - Triggers when the
release.ymlworkflow completes successfully (when a new tag is pushed) - Manual dispatch - Can be manually triggered from the Actions tab with an optional version parameter
For security, cryptographic keys are NEVER generated in GitHub Actions. Instead:
- Generate keys locally on your machine using
generate-keys-local.php - Copy them to GitHub Secrets manually
- Keys never leave your machine during generation
This ensures maximum security as private keys are never exposed to GitHub's infrastructure.
The workflow creates a PLC DID (Decentralized Identifier) for your package:
- Uses the generated cryptographic keys
- Submits to the PLC directory at
https://plc.directory - Adds a FAIR service endpoint pointing to your metadata
- Stores the DID as a secret for future use
For each release:
- Downloads the release ZIP created by
release.yml - Calculates SHA-256 checksum
- Signs the package with the verification key
- Generates FAIR-compliant
metadata.json - Uploads metadata to the GitHub release
Before following the setup steps above, ensure you have:
- A WordPress plugin with a main plugin file containing standard headers
- A GitHub repository with releases enabled
- PHP installed locally (for key generation)
- The
release.ymlworkflow (or similar) that creates releases from tags
To manually publish a specific version outside of the automatic release flow:
- Go to Actions tab in your repository
- Select "Publish to FAIR Repository" workflow
- Click "Run workflow" button (top right)
- Optionally enter a version (e.g.,
v0.0.1) or leave empty to use the latest tag - Click "Run workflow"
The workflow requires these secrets and variables:
| Secret Name | Purpose | How to Add |
|---|---|---|
FAIR_ROTATION_KEY_PRIVATE |
DID rotation key (secp256k1) | Generated locally in Step 2, added manually in Step 3 |
FAIR_ROTATION_KEY_PUBLIC |
DID rotation public key | Generated locally in Step 2, added manually in Step 3 |
FAIR_VERIFICATION_KEY_PRIVATE |
Package signing key (Ed25519) | Generated locally in Step 2, added manually in Step 3 |
FAIR_VERIFICATION_KEY_PUBLIC |
Package verification public key | Generated locally in Step 2, added manually in Step 3 |
| Variable Name | Purpose | How to Add |
|---|---|---|
FAIR_DID |
Your package's DID identifier | Generated by first workflow run, you must add manually as a variable (see Step 6) |
Important: Keys are generated locally using generate-keys-local.php for maximum security. Never generate private keys in GitHub Actions.
The workflow runs automatically whenever:
- You push a new tag (e.g.,
v1.0.0) - The
release.ymlworkflow completes successfully
No manual intervention required after initial setup!
To manually publish a specific version:
- Go to Actions tab in your repository
- Select "Publish to FAIR Repository" workflow
- Click "Run workflow"
- Optionally enter a version (leave empty to use latest tag)
- Click "Run workflow"
- Checks for existing cryptographic keys
- Generates new keys if none exist
- Saves keys as repository secrets in secrets
- Keys must be generated locally beforehand (never in Actions)
- Fails if keys are missing with instructionsting one
- Submits to PLC directory
- Updates with FAIR service endpoint
- Creates clean plugin ZIP archive
- Excludes development files (
.git,node_modules, etc.) - Calculates SHA-256 checksum
- Signs the package ZIP with verification key
- Generates cryptographic signature
- Ensures package integrity
- Parses plugin headers and
readme.txt - Generates FAIR-compliant
metadata.json - Includes release information, dependencies, and artifact details
- Uploads
fair-metadata.jsonto GitHub release - Makes metadata available at predictable URL
The generated metadata includes:
- Package information: name, description, slug, license
- Authors and security contacts
- Release details: version, dependencies, requirements
- Artifacts: package ZIP with signature and checksum
- Documentation sections: changelog, description, installation, etc.
Example metadata structure:
{
"@context": "https://fair.pm/ns/metadata/v1",
"id": "did:plc:abc123...",
"type": "wp-plugin",
"name": "Minimal Admin",
"license": "GPL-2.0+",
"releases": [
{
"version": "1.0.0",
"artifacts": {
"package": {
"url": "https://github.com/user/repo/releases/download/v1.0.0/plugin.zip",
"signature": "zQ3sh...",
"checksum": "sha256:abc..."
}
}
}
]
}This is expected behavior:
- KKeys not found error
If the workflow fails with "Cryptographic keys not found":
- Clone your repository locally
- Run:
php .github/scripts/fair/generate-keys-local.php - Copy the displayed keys to GitHub Secrets
- Re-run the workflow
This error should no longer occur - keys must be generated locally for security.
If the workflow can't find FAIR_DID:
- This is normal on first run
- A new DID will be created automatically
- Future runs will use the stored DID
Check that:
- Verification keys haven't been modified
- The workflow has completed successfully
- Artifact hasn't been modified after signing
Ensure:
- Your plugin has a main PHP file
- The file contains standard WordPress plugin headers
- The file includes
Plugin Name:header
.github/
├── scripts/fair/ # PHP scripts for FAIR operations
│ ├── manage-keys.php # Key generation and management
│ ├── create-did.php # DID creation and registration
│ ├── sign-artifact.php # Package signing
│ ├── generate-metadata.php # Metadata generation
│ └── update-did-service.php # DID service updates
└── workflows/
├── fair-publish.yml # Main FAIR publishing workflow
└── release.yml # GitHub release creation
- Never commit private keys to version control
- Keys are stored as encrypted GitHub secrets
- Only accessible to workflows with appropriate permissions
If you need to rotate keys:
- Delete the existing key secrets from repository settings
- Re-run the workflow to generate new keys
- Update your DID with new keys (handled automatically)
Users can verify package integrity:
- Check the signature against your verification key
- Verify checksum of downloaded artifact
- Validate DID authenticity via PLC directory
For issues or questions:
- Check the workflow logs in the Actions tab
- Review the FAIR Protocol documentation
- Open an issue in your repository
This workflow implementation follows the same license as your plugin project.