|
| 1 | +# GitHub Actions Workflows |
| 2 | + |
| 3 | +This directory contains all automated workflows for the ChurchCRM project. This document provides an overview of each workflow, its purpose, and when it runs. |
| 4 | + |
| 5 | +## Build & Test Workflows |
| 6 | + |
| 7 | +### build-test-package.yml |
| 8 | +**Purpose:** Main CI/CD pipeline for building, testing, and packaging ChurchCRM |
| 9 | + |
| 10 | +**Triggers:** |
| 11 | +- Pull requests to `master`, `develop`, or `hotfix/**` branches |
| 12 | +- Pushes to `master`, `develop`, or `hotfix/**` branches |
| 13 | +- Ignores changes to documentation, markdown files, and LICENSE |
| 14 | + |
| 15 | +**What it does:** |
| 16 | +1. **Build Job:** Compiles the application, validates PHP syntax, and creates build artifacts |
| 17 | +2. **Test Jobs (Parallel):** |
| 18 | + - `test-root`: Tests installation at root path (`/`) |
| 19 | + - `test-subdir`: Tests installation in subdirectory (`/churchcrm`) |
| 20 | +3. **Package Job:** Creates release artifacts with version-based naming |
| 21 | + |
| 22 | +**Key Features:** |
| 23 | +- Runs tests in parallel for faster CI feedback |
| 24 | +- Tests both root and subdirectory installation scenarios |
| 25 | +- Uploads build artifacts for releases |
| 26 | +- Comprehensive logging and Docker container logs on failure |
| 27 | + |
| 28 | +**Artifacts:** |
| 29 | +- `ChurchCRM-{version}.zip` for master branch |
| 30 | +- `ChurchCRM-{version}-PR{number}.zip` for pull requests |
| 31 | +- `cypress-artifacts-*` on test failures (logs, screenshots, videos) |
| 32 | + |
| 33 | +--- |
| 34 | + |
| 35 | +## Code Quality Workflows |
| 36 | + |
| 37 | +### ci.yml |
| 38 | +**Purpose:** Quick code quality checks for TypeScript and linting |
| 39 | + |
| 40 | +**Triggers:** |
| 41 | +- Pushes to `master` branch |
| 42 | +- Pull requests to `master` branch |
| 43 | + |
| 44 | +**What it does:** |
| 45 | +1. Runs TypeScript type checking (`tsc --noEmit`) |
| 46 | +2. Runs ESLint on React components |
| 47 | + |
| 48 | +**Key Features:** |
| 49 | +- Fast feedback on code quality issues |
| 50 | +- Runs independently from main build/test pipeline |
| 51 | +- Uses Node.js 22.x |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +## Localization Workflows |
| 56 | + |
| 57 | +### locale-poeditor-download.yml |
| 58 | +**Purpose:** Download and sync translations from POEditor translation platform |
| 59 | + |
| 60 | +**Triggers:** |
| 61 | +- **Scheduled:** Daily at midnight UTC |
| 62 | +- **Manual:** Via workflow_dispatch with options: |
| 63 | + - `operation_mode`: Choose between `download-and-audit` or `audit-only` |
| 64 | + - `skip_audit`: Skip audit step for faster execution |
| 65 | + |
| 66 | +**What it does:** |
| 67 | +1. Downloads latest translations from POEditor (requires `POEDITOR_TOKEN` secret) |
| 68 | +2. Validates download integrity (checks for empty files, regressions) |
| 69 | +3. Generates base term updates for locale variants (e.g., Portuguese variants) |
| 70 | +4. Generates missing terms reports for incomplete locales |
| 71 | +5. Runs locale audit to check translation completeness |
| 72 | +6. Creates a PR with all changes to `locale/{version}` branch |
| 73 | + |
| 74 | +**Key Features:** |
| 75 | +- Comprehensive validation prevents translation data loss |
| 76 | +- Detects and fails on locale regressions |
| 77 | +- Generates reports to help translators identify missing terms |
| 78 | +- Automatic PR creation with detailed changelog |
| 79 | + |
| 80 | +**Artifacts:** |
| 81 | +- Translation JSON files in `src/locale/i18n/` |
| 82 | +- Base term updates in `locale/base-term-updates/` |
| 83 | +- Missing terms reports in `locale/missing-terms/poeditor-*.json` |
| 84 | + |
| 85 | +### locale-update.yml |
| 86 | +**Purpose:** Generate translation terms from application source code |
| 87 | + |
| 88 | +**Triggers:** |
| 89 | +- Pushes to `master` branch that modify files in `src/**` |
| 90 | +- Manual trigger via workflow_dispatch |
| 91 | + |
| 92 | +**What it does:** |
| 93 | +1. Starts Docker containers for locale extraction |
| 94 | +2. Runs `npm run locale:build` to extract gettext strings from PHP/JS code |
| 95 | +3. Updates `locale/terms/messages.po` with new translatable strings |
| 96 | +4. Creates a PR if meaningful changes are detected (ignores header-only changes) |
| 97 | + |
| 98 | +**Key Features:** |
| 99 | +- Automatically detects new strings that need translation |
| 100 | +- Skips PR creation for trivial changes (header updates only) |
| 101 | +- Runs inside Docker to match production environment |
| 102 | +- Integrated with POEditor workflow for complete translation pipeline |
| 103 | + |
| 104 | +**Workflow Integration:** |
| 105 | +1. Developer adds `gettext()` or `i18next.t()` calls in code |
| 106 | +2. This workflow extracts new terms to `messages.po` |
| 107 | +3. Terms are uploaded to POEditor for translation |
| 108 | +4. `locale-poeditor-download.yml` brings translations back |
| 109 | + |
| 110 | +--- |
| 111 | + |
| 112 | +## Security Workflows |
| 113 | + |
| 114 | +### security-devskim.yml |
| 115 | +**Purpose:** Automated security vulnerability scanning using Microsoft DevSkim |
| 116 | + |
| 117 | +**Triggers:** |
| 118 | +- **Pushes:** To `master` or `develop` branches (when code files change) |
| 119 | +- **Pull Requests:** To `master` branch (when code files change) |
| 120 | +- **Scheduled:** Weekly on Mondays at 6:00 AM UTC |
| 121 | +- **Manual:** Via workflow_dispatch with options: |
| 122 | + - `scan_severity`: Minimum severity level (`low`, `medium`, `high`, `critical`) |
| 123 | + - `fail_on_error`: Whether to fail the workflow on security issues |
| 124 | + |
| 125 | +**What it does:** |
| 126 | +1. Installs Microsoft DevSkim CLI |
| 127 | +2. Scans all code files for security vulnerabilities |
| 128 | +3. Generates SARIF report with findings |
| 129 | +4. Uploads results to GitHub Security tab |
| 130 | +5. Creates step summary with issue counts and details |
| 131 | + |
| 132 | +**Key Features:** |
| 133 | +- Detects common security patterns (XSS, SQL injection, crypto issues, etc.) |
| 134 | +- Configurable severity threshold |
| 135 | +- Integrates with GitHub Security tab for issue tracking |
| 136 | +- Can be configured to fail builds on security issues |
| 137 | +- Archives SARIF results for 30 days |
| 138 | + |
| 139 | +**Scanned File Types:** |
| 140 | +- PHP, JavaScript, TypeScript |
| 141 | +- JSON, YAML, SQL |
| 142 | + |
| 143 | +### issue-comment.yml |
| 144 | +**Purpose:** Automated issue triage and security CVE handling |
| 145 | + |
| 146 | +**Triggers:** |
| 147 | +- When new issues are opened |
| 148 | + |
| 149 | +**What it does:** |
| 150 | +1. Detects issue type based on content: |
| 151 | + - **Security CVE/GHSA disclosures** (highest priority) |
| 152 | + - **System info reports** (in-app bug reporter) |
| 153 | + - **Bug reports** |
| 154 | + - **Questions** |
| 155 | + - **Generic** (fallback) |
| 156 | +2. Posts appropriate template comment from `.github/issue-comments/` |
| 157 | +3. **For security issues:** Automatically closes, labels, and directs to private disclosure |
| 158 | + |
| 159 | +**Key Features:** |
| 160 | +- Prevents public disclosure of security vulnerabilities |
| 161 | +- Automatically labels security issues with `security` and `security-delete-required` |
| 162 | +- Provides helpful guidance based on issue type |
| 163 | +- Thanks users who use the in-app bug reporter |
| 164 | + |
| 165 | +**Security Protection:** |
| 166 | +- Detects CVE-YYYY-NNNN and GHSA-xxxx-xxxx-xxxx patterns |
| 167 | +- Closes security issues immediately to prevent exploitation |
| 168 | +- Directs reporters to GitHub Security Advisories for private disclosure |
| 169 | +- Flags issues for manual deletion by repository admins |
| 170 | + |
| 171 | +--- |
| 172 | + |
| 173 | +## Automation Workflows |
| 174 | + |
| 175 | +### stale.yml |
| 176 | +**Purpose:** Automatically manage stale issues and pull requests |
| 177 | + |
| 178 | +**Triggers:** |
| 179 | +- **Scheduled:** Daily at 1:30 AM UTC |
| 180 | +- **Manual:** Via workflow_dispatch with options: |
| 181 | + - `dry_run`: Preview actions without making changes |
| 182 | + - `debug_only`: Enable debug logging |
| 183 | + |
| 184 | +**What it does:** |
| 185 | +1. Marks issues stale after 30 days of inactivity |
| 186 | +2. Marks PRs stale after 45 days of inactivity |
| 187 | +3. Closes stale items after 15 additional days |
| 188 | +4. Posts helpful messages explaining how to keep issues/PRs active |
| 189 | + |
| 190 | +**Key Features:** |
| 191 | +- Exempts security issues (labels: `security`, `vulnerability`, `cve`, `security-fix`) |
| 192 | +- Exempts pinned and high-priority items |
| 193 | +- Removes stale label when activity resumes |
| 194 | +- Friendly, helpful messages for contributors |
| 195 | +- Rate-limited to prevent API exhaustion (100 operations per run) |
| 196 | + |
| 197 | +**Exempt Labels:** |
| 198 | +- **Issues:** `pinned`, `security`, `vulnerability`, `cve`, `bug`, `enhancement`, `feature`, `good first issue`, `help wanted`, `priority:high`, `priority:critical`, `security-fix` |
| 199 | +- **PRs:** `pinned`, `security`, `vulnerability`, `security-fix`, `work-in-progress`, `do-not-merge`, `priority:high`, `priority:critical` |
| 200 | + |
| 201 | +### start-release.yml |
| 202 | +**Purpose:** Initiate a new release by updating version numbers |
| 203 | + |
| 204 | +**Triggers:** |
| 205 | +- **Manual only:** Via workflow_dispatch |
| 206 | +- **Required input:** `version` (e.g., "6.1.0") |
| 207 | + |
| 208 | +**What it does:** |
| 209 | +1. Runs `./scripts/startNewRelease.js` with the specified version |
| 210 | +2. Updates version in: |
| 211 | + - `package.json` and `package-lock.json` |
| 212 | + - `src/composer.json` and `src/composer.lock` |
| 213 | + - `src/mysql/upgrade.json` |
| 214 | + - `demo/ChurchCRM-Database.sql` |
| 215 | +3. Creates a new branch `build/{version}` |
| 216 | +4. Commits all version changes |
| 217 | +5. Creates a pull request to `master` branch |
| 218 | + |
| 219 | +**Key Features:** |
| 220 | +- Automated version bumping across all package files |
| 221 | +- Consistent version numbering |
| 222 | +- Creates clean release PRs |
| 223 | +- Integrates with main build pipeline when merged |
| 224 | + |
| 225 | +**Release Workflow:** |
| 226 | +1. Maintainer triggers this workflow with new version number |
| 227 | +2. Workflow creates PR with version updates |
| 228 | +3. PR is reviewed and merged to `master` |
| 229 | +4. `build-test-package.yml` creates release artifacts |
| 230 | +5. Artifacts are used to create GitHub release |
| 231 | + |
| 232 | +--- |
| 233 | + |
| 234 | +## Workflow Dependencies |
| 235 | + |
| 236 | +```mermaid |
| 237 | +graph LR |
| 238 | + A[Code Change] --> B[ci.yml] |
| 239 | + A --> C[build-test-package.yml] |
| 240 | + A --> D[locale-update.yml] |
| 241 | + A --> E[security-devskim.yml] |
| 242 | + D --> F[locale-poeditor-download.yml] |
| 243 | + F --> A |
| 244 | + G[New Issue] --> H[issue-comment.yml] |
| 245 | + I[Schedule] --> F |
| 246 | + I --> J[stale.yml] |
| 247 | + I --> E |
| 248 | + K[Manual] --> L[start-release.yml] |
| 249 | + L --> C |
| 250 | +``` |
| 251 | + |
| 252 | +--- |
| 253 | + |
| 254 | +## Best Practices |
| 255 | + |
| 256 | +### For Maintainers |
| 257 | + |
| 258 | +1. **Always review security-devskim.yml results** in the Security tab |
| 259 | +2. **Don't skip locale workflows** - translations are important for users |
| 260 | +3. **Use start-release.yml** instead of manually updating version numbers |
| 261 | +4. **Monitor stale.yml** to ensure important issues aren't auto-closed |
| 262 | + |
| 263 | +### For Contributors |
| 264 | + |
| 265 | +1. **Expect build-test-package.yml to run** on all PRs (takes ~15-20 minutes) |
| 266 | +2. **Fix ci.yml failures** before requesting review (TypeScript/lint errors) |
| 267 | +3. **Add gettext() wrapping** for new UI strings so locale-update.yml can extract them |
| 268 | +4. **Use GitHub Security Advisories** for security issues, not public issues |
| 269 | + |
| 270 | +--- |
| 271 | + |
| 272 | +## Secrets Required |
| 273 | + |
| 274 | +The following GitHub secrets must be configured for workflows to function: |
| 275 | + |
| 276 | +- `GITHUB_TOKEN` - Automatically provided by GitHub Actions (no configuration needed) |
| 277 | +- `POEDITOR_TOKEN` - API token for POEditor translation platform (required for locale-poeditor-download.yml) |
| 278 | + |
| 279 | +--- |
| 280 | + |
| 281 | +## Troubleshooting |
| 282 | + |
| 283 | +### Build Failures |
| 284 | + |
| 285 | +1. Check `build-test-package.yml` logs for specific error |
| 286 | +2. Download `cypress-artifacts-*` to see screenshots/videos of test failures |
| 287 | +3. Review Docker container logs in the artifact |
| 288 | +4. Check `src/logs/` in artifacts for PHP errors |
| 289 | + |
| 290 | +### Security Scan False Positives |
| 291 | + |
| 292 | +1. Review the finding in GitHub Security tab |
| 293 | +2. Add exception to `.devskim.json` if it's a false positive |
| 294 | +3. Document why it's a false positive in the configuration |
| 295 | + |
| 296 | +### Locale Issues |
| 297 | + |
| 298 | +1. Check POEditor for missing translations |
| 299 | +2. Review `locale/missing-terms/` for reports on incomplete locales |
| 300 | +3. Use `locale-poeditor-download.yml` manual trigger with `audit-only` mode |
| 301 | + |
| 302 | +--- |
| 303 | + |
| 304 | +## Maintenance Notes |
| 305 | + |
| 306 | +- **Last reviewed:** February 2026 |
| 307 | +- **Next review recommended:** August 2026 or when major GitHub Actions updates are released |
| 308 | + |
| 309 | +### Recent Changes |
| 310 | + |
| 311 | +- **February 2026:** Consolidated duplicate build workflows (removed old sequential version, kept parallel version) |
| 312 | +- **February 2026:** Added comprehensive workflow documentation |
0 commit comments