Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d216ce0
docs: add development guide
geekmuse Mar 29, 2026
6365ca4
docs: add documentation standards
geekmuse Mar 29, 2026
04781a1
docs: add README
geekmuse Mar 29, 2026
0c969b4
docs: add AGENTS.md with agent-facing conventions
geekmuse Mar 29, 2026
e32fe8c
docs: add CLAUDE.md with coding rules and patterns
geekmuse Mar 29, 2026
3d60961
docs: add CHANGELOG
geekmuse Mar 29, 2026
73b63cf
chore: add ralphi project configuration
geekmuse Mar 29, 2026
90278fe
chore: add docker-based quality check scripts
geekmuse Mar 29, 2026
bd12e91
docs(tasks): add comprehensive gap analysis
geekmuse Mar 29, 2026
a47077b
chore: add ralphi prd.json from gap analysis
geekmuse Mar 29, 2026
0e8cc3e
feat: [US-001] - Replace raw SQL helpers with getParam() API
geekmuse Mar 29, 2026
397dbfd
chore: update PRD, progress log, and AGENTS.md for US-001 completion
geekmuse Mar 29, 2026
cf75b64
feat: [US-002] Fix i18n parameter key strategy — use fixed English keys
geekmuse Mar 29, 2026
a34e0bf
chore: mark US-002 done in prd.json and append progress log
geekmuse Mar 29, 2026
9508a35
feat: [US-003] Add day-of-week guard to hasRequiredCondition()
geekmuse Mar 29, 2026
c9c00e8
feat: [US-004] - Add Saturday and Sunday color parameters
geekmuse Mar 29, 2026
4074a1f
feat: [US-005] - Add configurable timezone action parameter
geekmuse Mar 29, 2026
381b12d
feat: [US-006] PSR-12 indentation, phantom import, and strict compari…
geekmuse Mar 29, 2026
989ea2b
chore: mark US-006 done in PRD and append progress log
geekmuse Mar 29, 2026
2f9c500
feat: [US-007] - Add PHPDoc blocks to all classes and methods
geekmuse Mar 29, 2026
beb3b42
feat: [US-008] - Clarify date_due semantics in description and docume…
geekmuse Mar 29, 2026
fc99cad
feat: [US-009] - Add LICENSE file and fix plugin homepage URL
geekmuse Mar 29, 2026
2ca4ff2
feat: [US-010] - Add composer.json and PHPUnit test suite
geekmuse Mar 29, 2026
ca10de3
chore: mark US-010 done in PRD and append progress log
geekmuse Mar 29, 2026
d94f0f7
feat: [US-011] - Add CI pipeline
geekmuse Mar 29, 2026
2a83ef0
chore: update ralphi runtime state (all stories done)
geekmuse Mar 29, 2026
0f0dded
chore: merge ralph/gap-analysis-remediation into main
geekmuse Mar 29, 2026
22ed3df
docs: update documentation to reflect v0.2.0 delivered features
geekmuse Mar 29, 2026
21e8b58
chore: bump version to 0.2.0
geekmuse Mar 29, 2026
2d948d5
ci: add GitHub Actions workflows mirroring Gitea CI
geekmuse Mar 31, 2026
01a4744
ci(release): support prerelease tags in release workflow
geekmuse Mar 31, 2026
e3fab4c
ci: harden GitHub Actions supply-chain and repo security
geekmuse Mar 31, 2026
c7cb188
chore(deps): update phpstan/phpstan requirement || ^2.0
dependabot[bot] Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .gitea/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
ci:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

# Stage 1 — PHP syntax check
# Uses kanboard/kanboard image with entrypoint override (default entrypoint
# starts Apache and runs forever; we override to /bin/sh for one-shot use).
- name: Lint — PHP syntax check
run: bash scripts/docker-lint.sh

# Stage 2 — Install Composer dependencies
# vendor/ is not committed (.gitignore); install it here so the remaining
# stages can find vendor/bin/phpcs, vendor/bin/phpstan, vendor/bin/phpunit.
- name: Install Composer dependencies
run: |
docker run --rm \
-v "$PWD":/app \
composer:2 \
install --no-interaction --prefer-dist --no-progress

# Stage 3 — PSR-12 code style check
- name: PHPCS — PSR-12 style check
run: bash scripts/docker-phpcs.sh

# Stage 4 — Static analysis (PHPStan level 5)
# Uses php:8.4-cli — kanboard/kanboard lacks the tokenizer extension
# required by PHPStan.
- name: PHPStan — static analysis
run: bash scripts/docker-phpstan.sh

# Stage 5 — Unit tests
# Uses php:8.4-cli for the same reason as PHPStan above.
- name: PHPUnit — unit tests
run: bash scripts/docker-test.sh
22 changes: 22 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: 2

updates:
# Keep GitHub Actions pinned SHAs up to date.
# Dependabot will open PRs to bump the SHA comments and the hash itself
# whenever a new release of a used action is published.
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
commit-message:
prefix: "chore(ci)"

# Keep Composer dev dependencies (phpunit, phpstan) up to date.
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
commit-message:
prefix: "chore(deps)"
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
ci:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

# Stage 1 — PHP syntax check
# Uses kanboard/kanboard image with entrypoint override (default entrypoint
# starts Apache and runs forever; we override to /bin/sh for one-shot use).
- name: Lint — PHP syntax check
run: bash scripts/docker-lint.sh

# Stage 2 — Install Composer dependencies
# vendor/ is not committed (.gitignore); install it here so the remaining
# stages can find vendor/bin/phpcs, vendor/bin/phpstan, vendor/bin/phpunit.
- name: Install Composer dependencies
run: |
docker run --rm \
-v "$PWD":/app \
composer:2 \
install --no-interaction --prefer-dist --no-progress

# Stage 3 — PSR-12 code style check
- name: PHPCS — PSR-12 style check
run: bash scripts/docker-phpcs.sh

# Stage 4 — Static analysis (PHPStan level 5)
# Uses php:8.4-cli — kanboard/kanboard lacks the tokenizer extension
# required by PHPStan.
- name: PHPStan — static analysis
run: bash scripts/docker-phpstan.sh

# Stage 5 — Unit tests
# Uses php:8.4-cli for the same reason as PHPStan above.
- name: PHPUnit — unit tests
run: bash scripts/docker-test.sh
37 changes: 37 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CodeQL

on:
push:
branches:
- main
pull_request:
branches:
- main
schedule:
# Weekly scan every Monday at 03:00 UTC, independent of push activity.
- cron: '0 3 * * 1'

jobs:
analyze:
name: Analyze (PHP)
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read

steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Initialize CodeQL
uses: github/codeql-action/init@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3.35.1
with:
languages: php
# Use the security-extended suite for broader PHP vulnerability coverage
# (SQL injection, path traversal, XSS, SSRF, etc.)
queries: security-extended

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5c8a8a642e79153f5d047b10ec1cba1d1cc65699 # v3.35.1
with:
category: "/language:php"
65 changes: 65 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Release

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'

jobs:
release:
runs-on: ubuntu-latest
environment: release
permissions:
contents: write

steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF_NAME#v}
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
# Mark as prerelease if version contains a hyphen (e.g. 0.3.0-rc.1)
if [[ "$VERSION" == *-* ]]; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi

# Build a distributable plugin ZIP.
# Kanboard's plugin installer expects a ZIP containing a single root
# directory named exactly after the plugin class: AssignColorsByDayOfWeek.
# This plugin has no production Composer dependencies (require-dev only),
# so vendor/ is intentionally excluded from the archive.
- name: Build plugin archive
run: |
ARCHIVE="AssignColorsByDayOfWeek-${{ steps.version.outputs.version }}.zip"
PLUGIN_DIR="AssignColorsByDayOfWeek"

mkdir -p "dist/$PLUGIN_DIR"
cp -r Action "dist/$PLUGIN_DIR/"
cp Plugin.php LICENSE README.md CHANGELOG.md composer.json "dist/$PLUGIN_DIR/"

cd dist
zip -r "../$ARCHIVE" "$PLUGIN_DIR/"
cd ..

echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV"

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
PRERELEASE_FLAG=""
if [ "${{ steps.version.outputs.prerelease }}" = "true" ]; then
PRERELEASE_FLAG="--prerelease"
fi

gh release create "${{ github.ref_name }}" \
--title "${{ github.ref_name }}" \
--generate-notes \
$PRERELEASE_FLAG \
"$ARCHIVE"
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Composer dependencies — install with: docker run --rm -v "$PWD:/app" composer:2 install
/vendor/

# Composer lock file — intentionally not committed for a library/plugin
# (consumers pin their own dependency versions)
/composer.lock

# PHPStan result cache
/.phpstan.result.cache
/.phpstan-cache/

# PHPUnit result cache and coverage reports
/.phpunit.result.cache
/.phpunit.cache/
/coverage/
1 change: 1 addition & 0 deletions .ralphi/.last-branch
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ralph/gap-analysis-remediation
42 changes: 42 additions & 0 deletions .ralphi/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ralphi configuration
# Auto-generated — edit as needed

project:
name: "plugin-auto-action-assign-colors-by-day-of-week"
description: "A Kanboard plugin that automatically assigns task card colors based on the day of the week of the task's due date, triggered at task creation."
language: "PHP"
framework: "Kanboard Plugin"

commands:
lint: "bash scripts/docker-lint.sh"
test: "bash scripts/docker-test.sh"
phpcs: "bash scripts/docker-phpcs.sh"
phpstan: "bash scripts/docker-phpstan.sh"
# build: n/a — PHP plugin loaded directly by Kanboard
# typecheck: n/a — covered by phpstan

rules:
# ── Docker ────────────────────────────────────────────────────────────────
- "WHEN running any command in the kanboard/kanboard Docker image you MUST override the entrypoint — the default entrypoint starts Apache and runs forever. Always use: docker run --rm --entrypoint /bin/sh kanboard/kanboard -c \"<cmd>\""

# ── Kanboard plugin API ───────────────────────────────────────────────────
- "use $this->getParam('Monday') (and other day names) to read action parameters — NEVER query action_has_params directly; ActionManager already populates $this->params for each action instance before execute() is called"
- "use $this->getProjectId() to retrieve the action's configured project — do not pass project_id through helper methods"
- "all database queries must use PicoDb query builder or PDO prepared statements — no raw SQL string interpolation"
- "all user-visible strings wrapped in t('...') for localization"
- "follow PSR-12 coding standard — 4-space indentation for PHP, no mixed tabs and spaces"

# ── Action lifecycle ──────────────────────────────────────────────────────
- "hasRequiredCondition() must guard ALL failure paths before doAction() is called — doAction() should be unconditional given a passing condition"
- "parameter keys in getActionRequiredParameters() and parameter lookups in doAction()/helpers must use the same key strategy (either fixed English strings OR t() applied consistently to both sides)"

# ── Known gaps (see docs/tasks/001-gap-analysis.md) ──────────────────────
- "BEFORE ANY CODING WORK each iteration: read docs/tasks/001-gap-analysis.md — it contains the prioritized gap list and maps each gap to concrete tasks"

boundaries:
never_touch:
- "*.lock"
- ".env*"

engine: "pi"
max_retries: 3
Loading
Loading