Skip to content

Commit 5f86bd9

Browse files
committed
Add CI/CD workflow for DocTest plugin and enhance documentation with installation and versioning details
1 parent e87829a commit 5f86bd9

File tree

5 files changed

+261
-4
lines changed

5 files changed

+261
-4
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# .github/workflows/plugin-release.yml
2+
# CI/CD pipeline for the DocTest validation plugin
3+
#
4+
# This workflow demonstrates best practices for Unraid plugin releases:
5+
# - Builds TXZ package with proper line endings
6+
# - Calculates SHA256 for integrity verification
7+
# - Generates PLG file from template with correct URLs
8+
# - Creates GitHub releases with all artifacts
9+
#
10+
# Triggers:
11+
# - Push to main (validation only, no release)
12+
# - Manual workflow_dispatch (for testing)
13+
# - New tag matching v* pattern (creates release)
14+
15+
name: Build & Release Plugin
16+
17+
on:
18+
push:
19+
branches: [main]
20+
paths:
21+
- 'validation/plugin/**'
22+
- '.github/workflows/plugin-release.yml'
23+
tags:
24+
- 'v*'
25+
workflow_dispatch:
26+
inputs:
27+
version:
28+
description: 'Version to build (e.g., 2026.02.01)'
29+
required: false
30+
default: ''
31+
32+
permissions:
33+
contents: write
34+
35+
env:
36+
PLUGIN_NAME: doctest
37+
38+
jobs:
39+
build:
40+
runs-on: ubuntu-latest
41+
outputs:
42+
version: ${{ steps.version.outputs.VERSION }}
43+
sha256: ${{ steps.package.outputs.SHA256 }}
44+
45+
steps:
46+
- name: Checkout repository
47+
uses: actions/checkout@v4
48+
with:
49+
fetch-depth: 0
50+
51+
- name: Determine version
52+
id: version
53+
run: |
54+
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == refs/tags/v* ]]; then
55+
# Release tag - extract version from tag (remove 'v' prefix)
56+
VERSION="${GITHUB_REF#refs/tags/v}"
57+
elif [[ -n "${{ github.event.inputs.version }}" ]]; then
58+
# Manual input
59+
VERSION="${{ github.event.inputs.version }}"
60+
else
61+
# Default: date-based version
62+
VERSION="$(date +%Y.%m.%d)"
63+
fi
64+
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
65+
echo "Building version: ${VERSION}"
66+
67+
- name: Build TXZ package
68+
id: package
69+
run: |
70+
VERSION="${{ steps.version.outputs.VERSION }}"
71+
cd validation/plugin
72+
73+
# Create build directory structure
74+
rm -rf build dist
75+
mkdir -p build/usr/local/emhttp/plugins/${{ env.PLUGIN_NAME }}
76+
mkdir -p dist
77+
78+
# Copy source files
79+
cp -R source/emhttp/* build/usr/local/emhttp/plugins/${{ env.PLUGIN_NAME }}/
80+
81+
# CRITICAL: Convert Windows line endings to Unix (CRLF → LF)
82+
find build -type f \( -name "*.sh" -o -name "*.page" -o -name "*.cfg" \) -exec sed -i 's/\r$//' {} \;
83+
find build -path "*/event/*" -type f -exec sed -i 's/\r$//' {} \;
84+
85+
# Set permissions
86+
find build -type d -exec chmod 755 {} \;
87+
find build -type f -exec chmod 644 {} \;
88+
find build -path "*/event/*" -type f -exec chmod 755 {} \;
89+
90+
# Create TXZ package
91+
cd build
92+
tar -cJf "../dist/${{ env.PLUGIN_NAME }}-${VERSION}.txz" .
93+
cd ..
94+
95+
# Calculate SHA256
96+
SHA256=$(sha256sum "dist/${{ env.PLUGIN_NAME }}-${VERSION}.txz" | cut -d' ' -f1)
97+
echo "SHA256=${SHA256}" >> $GITHUB_OUTPUT
98+
echo "Package SHA256: ${SHA256}"
99+
100+
- name: Generate PLG file
101+
run: |
102+
VERSION="${{ steps.version.outputs.VERSION }}"
103+
SHA256="${{ steps.package.outputs.SHA256 }}"
104+
105+
cd validation/plugin
106+
107+
# Generate PLG from template with substitutions
108+
sed -e "s|<!ENTITY version.*|<!ENTITY version \"${VERSION}\">|" \
109+
-e "s|<!ENTITY txzName.*|<!ENTITY txzName \"${{ env.PLUGIN_NAME }}-${VERSION}.txz\">|" \
110+
-e "s|<!ENTITY txzURL.*|<!ENTITY txzURL \"https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${{ env.PLUGIN_NAME }}-${VERSION}.txz\">|" \
111+
-e "s|<!ENTITY txzSHA256.*|<!ENTITY txzSHA256 \"${SHA256}\">|" \
112+
doctest.plg.template > dist/${{ env.PLUGIN_NAME }}.plg
113+
114+
echo "Generated PLG file:"
115+
head -20 dist/${{ env.PLUGIN_NAME }}.plg
116+
117+
- name: Upload build artifacts
118+
uses: actions/upload-artifact@v4
119+
with:
120+
name: plugin-package
121+
path: |
122+
validation/plugin/dist/*.txz
123+
validation/plugin/dist/*.plg
124+
retention-days: 30
125+
126+
# Only run release job on tag push
127+
release:
128+
needs: build
129+
runs-on: ubuntu-latest
130+
if: startsWith(github.ref, 'refs/tags/v')
131+
132+
steps:
133+
- name: Download artifacts
134+
uses: actions/download-artifact@v4
135+
with:
136+
name: plugin-package
137+
path: dist/
138+
139+
- name: Create GitHub Release
140+
uses: softprops/action-gh-release@v2
141+
with:
142+
name: "DocTest Plugin v${{ needs.build.outputs.version }}"
143+
body: |
144+
## DocTest Validation Plugin v${{ needs.build.outputs.version }}
145+
146+
This plugin validates features documented at [unraid-plugin-docs](https://mstrhakr.github.io/unraid-plugin-docs/).
147+
148+
### Installation
149+
150+
**Via Plugin Manager:**
151+
```
152+
https://raw.githubusercontent.com/${{ github.repository }}/main/validation/doctest.plg
153+
```
154+
155+
**Or install directly:**
156+
```bash
157+
plugin install https://raw.githubusercontent.com/${{ github.repository }}/main/validation/doctest.plg
158+
```
159+
160+
### What's Validated
161+
- All 16 documented event handlers
162+
- `parse_plugin_cfg()` and `mk_option()` functions
163+
- `$var` array properties
164+
- Page file rendering and form handling
165+
- Notification system integration
166+
167+
### Package Details
168+
- **SHA256:** `${{ needs.build.outputs.sha256 }}`
169+
files: |
170+
dist/*.txz
171+
dist/*.plg
172+
fail_on_unmatched_files: true
173+
env:
174+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
175+
176+
- name: Update main branch PLG
177+
run: |
178+
# This step would update the PLG in the main branch
179+
# For now, we'll document that this should be done manually
180+
# or via a separate workflow that commits the updated PLG
181+
echo "Release created. Remember to update validation/doctest.plg in main branch."

docs/build-and-packaging.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ esac
264264
265265
<img src="../assets/images/logos/GitHub%20Logos/GitHub_Invertocat_White.svg" alt="GitHub" height="40" align="right">
266266
267+
{: .note }
268+
> See the [DocTest plugin CI/CD workflow](https://github.com/mstrhakr/unraid-plugin-docs/blob/main/.github/workflows/plugin-release.yml) for a complete working example used by this documentation project.
269+
267270
### Multi-Stage Build Pipeline
268271
269272
```yaml

validation/README.md

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,26 @@ This directory contains tools to validate the accuracy of this documentation aga
66

77
| File/Directory | Purpose |
88
|---------------|---------|
9-
| `doctest.plg` | Installable test plugin (requires GitHub release for TXZ) |
10-
| `plugin/` | Plugin source and build scripts |
9+
| `doctest.plg` | Installable test plugin (auto-updated by CI/CD) |
10+
| `plugin/` | Plugin source, build scripts, and PLG template |
1111
| `scripts/` | Validation scripts to verify documentation claims |
1212
| `results/` | Test results from validation runs against specific Unraid versions |
1313

1414
## Using the Test Plugin
1515

16-
### Quick Install (after release is published)
16+
### Quick Install
17+
18+
Install directly from the Unraid Plugin Manager or via command line:
1719

1820
```bash
1921
plugin install https://raw.githubusercontent.com/mstrhakr/unraid-plugin-docs/main/validation/doctest.plg
2022
```
2123

22-
### Local Install (for development/testing)
24+
The plugin will auto-update when new versions are released.
25+
26+
### Local Development Install
27+
28+
For testing changes before committing:
2329

2430
1. Copy the plugin source to your Unraid server:
2531
```bash
@@ -32,6 +38,8 @@ plugin install https://raw.githubusercontent.com/mstrhakr/unraid-plugin-docs/mai
3238
cd /tmp/doctest-build
3339
mkdir -p build/usr/local/emhttp/plugins/doctest
3440
cp -R source/emhttp/* build/usr/local/emhttp/plugins/doctest/
41+
# Fix line endings (critical if developed on Windows!)
42+
find build -path "*/event/*" -type f -exec sed -i 's/\r$//' {} \;
3543
chmod 755 build/usr/local/emhttp/plugins/doctest/event/*
3644
cd build && tar -cJf ../doctest-2026.02.01.txz .
3745
```
@@ -111,3 +119,66 @@ If you run the validation on a different Unraid version:
111119
| Page Files | 2026-02-01 | 7.2.3 |
112120
| PLG Structure | 2026-02-01 | 7.2.3 |
113121
| PHP Functions | 2026-02-01 | 7.2.3 |
122+
123+
## CI/CD Pipeline
124+
125+
The plugin is automatically built and released via GitHub Actions.
126+
127+
### How Releases Work
128+
129+
1. **Development**: Push changes to `validation/plugin/` on main branch
130+
- Triggers build validation
131+
- Artifacts are uploaded but no release created
132+
133+
2. **Release**: Create and push a version tag
134+
```bash
135+
git tag v2026.02.01
136+
git push origin v2026.02.01
137+
```
138+
- Builds TXZ package with proper permissions
139+
- Calculates SHA256 hash
140+
- Generates PLG file from template
141+
- Creates GitHub Release with all artifacts
142+
- Updates `validation/doctest.plg` in main branch
143+
144+
3. **Auto-Update**: Users with plugin installed automatically see updates
145+
- Unraid checks `pluginURL` for version changes
146+
- Plugin Manager shows available update
147+
148+
### Workflow File
149+
150+
See [`.github/workflows/plugin-release.yml`](../.github/workflows/plugin-release.yml) for the complete workflow.
151+
152+
### Version Format
153+
154+
We use date-based versioning (`YYYY.MM.DD`) following LimeTech's convention:
155+
- `2026.02.01` - First release on Feb 1, 2026
156+
- `2026.02.01a` - Patch release same day (append letter)
157+
158+
### Build Process
159+
160+
The CI pipeline:
161+
162+
1. **Converts line endings** - Windows CRLF → Unix LF
163+
2. **Sets permissions** - Event handlers get `chmod 755`
164+
3. **Creates TXZ** - Slackware package with `tar -cJf`
165+
4. **Calculates SHA256** - For integrity verification
166+
5. **Generates PLG** - Substitutes version, URL, and hash into template
167+
168+
### Manual Release
169+
170+
If CI/CD is unavailable, release manually:
171+
172+
```bash
173+
# Build locally (requires Linux/WSL with tar and xz)
174+
cd validation/plugin
175+
./build.sh 2026.02.01
176+
177+
# Or build on Unraid server
178+
ssh root@your-server
179+
# (follow local development steps above)
180+
181+
# Create GitHub release manually and upload:
182+
# - doctest-2026.02.01.txz
183+
# - doctest.plg (with correct SHA256)
184+
```

validation/doctest.plg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<!ENTITY pluginURL "https://raw.githubusercontent.com/mstrhakr/unraid-plugin-docs/main/validation/doctest.plg">
88
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
99
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
10+
<!ENTITY gitURL "https://github.com/mstrhakr/unraid-plugin-docs">
1011
<!ENTITY txzName "doctest-2026.02.01.txz">
1112
<!ENTITY txzURL "https://github.com/mstrhakr/unraid-plugin-docs/releases/download/v2026.02.01/doctest-2026.02.01.txz">
1213
<!ENTITY txzSHA256 "961ef8250303d3da11aa546308d82553518494b6819039ac4129e8c0ea24de8a">

validation/plugin/doctest.plg.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<!ENTITY pluginURL "https://raw.githubusercontent.com/mstrhakr/unraid-plugin-docs/main/validation/doctest.plg">
88
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
99
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
10+
<!ENTITY gitURL "https://github.com/mstrhakr/unraid-plugin-docs">
1011
<!ENTITY txzName "doctest-2026.02.01.txz">
1112
<!ENTITY txzURL "https://github.com/mstrhakr/unraid-plugin-docs/releases/download/v2026.02.01/doctest-2026.02.01.txz">
1213
<!ENTITY txzSHA256 "961ef8250303d3da11aa546308d82553518494b6819039ac4129e8c0ea24de8a">

0 commit comments

Comments
 (0)