From 5d79e185006bd916dce450849b4f3d172d13c317 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 22:52:27 +0000 Subject: [PATCH 01/14] docs: fix critical issues in copilot-instructions.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix 9 issues identified in comprehensive analysis: Critical fixes: - Fix incorrect line reference (line 258 → 269) - Fix gh pr merge flag syntax (-md → -m -d in 3 locations) - Add --severity=style flag to shellcheck command Quick wins: - Add safety warning for @production WP CLI usage - Remove duplicate branch deployment section - Fix section numbering (restart for each language) Low priority improvements: - Expand "After pushing" section with 4 tasks - Clarify has_block() is WordPress function - Improve gh_check_merge alias phrasing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 411 ++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 shell/copilot-instructions.md diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md new file mode 100644 index 0000000..e7f1af0 --- /dev/null +++ b/shell/copilot-instructions.md @@ -0,0 +1,411 @@ +# Copilot CLI Instructions for Itineris Development + +## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing + +**NEVER push to GitHub without running local lint checks first.** + +For Bash scripts, ALWAYS run before pushing: +```bash +# 1. Check and remove trailing whitespace +git diff --check && sed -i 's/[[:space:]]*$//' script-name + +# 2. Format with shfmt +shfmt -w script-name && shfmt -d script-name + +# 3. Run ShellCheck at style severity (matches CI) +shellcheck --format=gcc --severity=style script-name +``` + +For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for specific commands. + +**Zero tolerance policy**: Fix all issues locally. Do not rely on CI to catch problems. + +**When to run lint checks:** +- Ideally: Before committing (catches issues early) +- Mandatory: Before pushing (prevents CI failures) +- Best practice: Set up pre-commit hooks to automate this + +--- + +## Language & Spelling + +- **Always use British English** for all code, comments, documentation, commit messages, and communication +- Common British English spellings to use: + - "optimise" not "optimize" + - "colour" not "color" + - "behaviour" not "behavior" + - "centre" not "center" + - "licence" (noun) / "license" (verb) + - "analyse" not "analyze" +- This applies to variable names, function names, comments, strings, and all written content + +## PHP & WordPress Best Practices + +### Variable Handling + +- **NEVER use `global $post`** - Always use `get_post()` instead +- **Always check types properly** - Use `instanceof ClassName` instead of truthy checks +- Import classes with `use` statements at the top of files, not Fully Qualified Names (FQNs) inline + +### Code Quality + +- **Remove all trailing whitespace** - Code must be clean +- **Follow WordPress Coding Standards** strictly +- Use `printf()` or `sprintf()` for HTML construction instead of string concatenation with `echo` +- Escape all output appropriately: + - `esc_url()` for URLs + - `esc_attr()` for HTML attributes + - `esc_html()` for HTML content + - Do not mix `esc_xxx` functions with Blade `{{ }}`. Prefer using WordPress functions with unescaped Blade echo `{!! !!}`. + - INCORRECT: `{{ esc_html($var) }}` + - CORRECT: `{!! esc_html($var) !!}` +- Add phpcs ignore comments with explanations when escaping is already handled +- Do not use `get_posts` or `get_terms`. Use their related query classes `WP_Query` and `WP_Term_Query` + +### Code Style + +- Keep lines under 120 characters +- Add trailing commas to multi-line function calls (PHP 8.0+) +- Use descriptive function and variable names to avoid using comments for explanations. +- Use strict types instead of PHPDoc blocks unless required +- Only use PHPDoc blocks if function or variable names are not clear +- Extract duplicate code into helper functions or methods +- Use `PHP_EOL` for line breaks instead of `"\n"` for consistency + +### Error Handling + +- Always validate JSON decoding with `json_last_error()` and type checks +- Check if resources exist before using them +- Add early returns for guard clauses + +### Compiler-Optimised Functions + +- Always import internal PHP functions with `use function` at the top of the file +- Common functions to import: `strlen`, `count`, `is_array`, `in_array`, `array_key_exists`, etc. +- This enables compiler optimisations for better performance +- Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code +- This is a micro-optimisation but matters when functions are called frequently + +## Git Workflow + +### Critical Pre-Push Requirements + +**BEFORE PUSHING TO GITHUB:** +1. **ALWAYS run lint checks locally** - See "Before Committing" section below for specific commands +2. **ALWAYS verify checks pass** - Zero failures allowed +3. **NEVER push without local validation** - CI failures waste time and create noise + +### Branch Protection + +- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) +- **ALWAYS create a feature branch** for any changes +- **ALWAYS create a Pull Request** for review before merging + +### Complete Workflow (Order of Operations) + +When implementing a feature or fix: + +1. **Create feature branch** - If on default branch, create and switch to feature branch first +2. **Push branch immediately** - `git push -u origin ` for visibility +3. **Open draft PR early** - Include implementation plan, links to tickets +4. **Make changes & commit after each phase** - Use conventional commit format +5. **Push after each commit** - Enable real-time review on GitHub +6. **Mark PR as "Ready for Review"** - When all phases complete and tests pass +7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed +8. **Deploy to staging for testing** - `git push origin :staging --force` +9. **Verify changes on staging** - Test that the fix/feature works correctly +10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` +11. **Production deployment** - Happens automatically when default branch is pushed + +**Key points:** +- Always verify on staging BEFORE merging to default branch +- Never merge to default branch without staging verification +- Merging to default branch triggers automatic production deployment + +### Feature Branch Workflow + +When implementing a feature with an implementation plan: + +1. **Check current branch** - If on default branch, create and switch to a feature branch first +2. **Create feature branch** with naming based on ticket source: + - **ClickUp**: `clickup//` (e.g., `clickup/86bzphaee/landing-page-ammends`) + - **FreshDesk**: `freshdesk//` (e.g., `freshdesk/21170/intro-section-image-position`) + - **GitHub Issues**: `issue//` (e.g., `issue/123/fix-navigation-bug`) + - **General** (no ticket): `feature/` or `fix/` (e.g., `feature/add-caching`, `fix/header-spacing`) +3. **Push branch immediately** to GitHub for visibility +4. **Open draft PR early** with: + - Implementation plan in the description + - Clear title describing the feature + - Links to related tickets/documents +5. **Commit after each phase** with conventional commit messages +6. **Push after each commit** for real-time review on GitHub +7. **Update PR description** with progress checkpoints as you go +8. **Mark PR as "Ready for Review"** when all phases complete and tests pass + +### Commits + +- Write clear, descriptive commit messages +- Use conventional commit format when appropriate (feat:, fix:, docs:, test:, refactor:) +- Explain the "why" not just the "what" in commit messages +- Include context about what problem is being solved +- Commit frequently - after each logical phase or component completion +- Push commits regularly so work can be reviewed incrementally + +### Pull Requests + +- Create descriptive PR titles and descriptions +- Include "Overview", "Related Tickets & Documents" sections, "Changes", "Impact", "Testing", "Before/After" +- Prompt user for ClickUp, FreshDesk, GitHub, or Sentry links for the "Related Tickets & Documents" section +- Search for related PRs/issues yourself after asking the user +- Open PRs early as drafts to enable real-time review +- Run linting and tests before pushing + +### Branch Deployment + +- To deploy any branch to an environment: push that branch to the environment branch + - **Staging deployment**: `git push origin :staging --force` + - **Production deployment**: Happens automatically when default branch is pushed +- Works for feature branches, fix branches, or any other branch +- This triggers the CD workflow which deploys to the corresponding environment +- Verify changes on the target environment before proceeding + +### Testing on Remote Environments + +- **WP CLI aliases** are configured in `wp-cli.yml` for remote testing: + - `@staging` - Staging environment + - `@production` - Production environment + - **⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete) +- Use aliases to test WP CLI commands on remote servers: + - Example: `wp @staging option get home` + - Example: `wp @staging cli version` +- Always test on staging after deployment to verify fixes work correctly + +### Code Review + +**Getting PR Comments:** +Use `gh-pr-get-comments` script to retrieve all comments on a PR: +```bash +# Get all comments in pretty format +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author (e.g., Copilot bot) +~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' + +# Get unresolved review comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# Get JSON output for parsing +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +**Addressing Review Feedback:** +1. Review all comments from code reviewers and validate their accuracy +2. Discuss false-positives or questionable feedback before making changes +3. Don't just make the minimal change - understand and fix the underlying issue +4. Reply to each comment individually in its thread using `gh-pr-reply-to-thread`: + ```bash + # Reply to a review thread (use thread-id from gh-pr-get-comments output) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' + + # Reply and resolve thread in one command + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + + # Resolve thread without replying (e.g., false positive) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only + ``` +5. Include commit links when referencing fixes in replies +6. Resolve threads when issues are fixed, leave unresolved if dismissing/rejecting feedback +7. Re-run linting after addressing comments +8. Push changes promptly to unblock merging +9. After addressing all feedback and pushing, request a new review from Copilot: + ```bash + gh pr edit --add-reviewer @copilot + ``` + +**Important:** Always use the utility scripts (`gh-pr-get-comments` and `gh-pr-reply-to-thread`) instead of raw `gh api` calls for PR comment management. + +### Merging to Default Branch + +- Before merging, ensure the most recent commit was deployed to staging and verified +- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch + - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) + - The `--admin` flag bypasses branch protection rules + - The `-m -d` flags merge and delete the branch after merging +- **Note**: This is only for merging to the default branch, NOT for deploying to staging + +### Deploying to Staging + +See the "Branch Deployment" section above for complete deployment instructions. + +## Development Workflow + +### API Queries + +**GitHub PR Comments:** +- **Get comments**: Use `~/Code/misc/itineris-bin/gh-pr-get-comments` to retrieve PR comments +- **Reply to comments**: Use `~/Code/misc/itineris-bin/gh-pr-reply-to-thread` to reply and resolve threads +- See "Code Review" section for detailed usage examples + +**Task/Ticket Management:** +- **ClickUp**: Use `~/Code/misc/itineris-bin/clickup-get-task` to query ClickUp tasks +- **FreshDesk**: Use `~/Code/misc/itineris-bin/freshdesk-get-ticket` to query FreshDesk tickets +- These scripts handle authentication and API interaction automatically +- Always use these dedicated scripts instead of making direct API calls + +### Accessing Credentials + +- Use 1Password CLI (`op` or `op.exe` on Windows/WSL) to retrieve credentials programmatically +- Example: `op item get "Item Name" --vault "Vault Name" --fields username,password` +- Check project documentation for specific vault and item names + +### Before Committing + +**CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** + +#### For PHP Changes + +1. Run PHP syntax check: `php -l ` +2. Run phpcs linting: `./vendor/bin/phpcs --standard=phpcs.xml ` +3. Auto-fix with phpcbf if needed: `./vendor/bin/phpcbf --standard=phpcs.xml ` + +#### For JavaScript/CSS Changes + +1. For JS changes, run linter with auto-fix if available (e.g., `eslint --fix`) +2. For CSS changes, run linter with auto-fix if available (e.g., `stylelint --fix`) + +#### For Bash Script Changes + +**MANDATORY: Run ALL these checks before committing ANY Bash script changes:** + +```bash +# 1. Remove trailing whitespace (REQUIRED) +sed -i 's/[[:space:]]*$//' script-name + +# Verify no trailing whitespace in staged changes +git diff --check + +# 2. Format with shfmt (REQUIRED) +shfmt -w script-name + +# Verify formatting is correct +shfmt -d script-name + +# 3. Run ShellCheck with CI-equivalent settings (REQUIRED) +# This must match the severity level used in CI (style severity) +shellcheck --format=gcc --severity=style script-name + +# Or check all modified scripts in your branch +git diff main --name-only --diff-filter=ACMR | \ + xargs shellcheck --format=gcc --severity=style +``` + +**Important ShellCheck Notes:** +- Use `--severity=style` to match CI configuration (not `--severity=warning`) +- Some repositories use differential-shellcheck which checks at "style" level +- SC1091 (sourcing external files) and SC2016 (single quotes) may be acceptable depending on context +- **Zero tolerance policy**: If CI will fail, fix it locally first + +**MANDATORY Pre-Commit Checklist for Bash Scripts:** +- ✅ Trailing whitespace removed (`git diff --check` shows nothing) +- ✅ Script formatted with shfmt (`shfmt -d script-name` shows no diff) +- ✅ ShellCheck passes at style severity (`shellcheck --severity=style`) +- ✅ All variables use `${VAR}` syntax (not `$VAR`) +- ✅ Script tested manually with `--help` flag (if applicable) +- ✅ Documentation updated (README, etc.) + +#### General + +1. Verify all tests pass (if applicable) + +### Testing GitHub Actions Locally + +Before pushing CI workflow changes, test them locally using the [act GitHub CLI extension](https://nektosact.com/installation/gh.html): + +```bash +# Install act as a GitHub CLI extension +gh extension install https://github.com/nektos/gh-act + +# Test workflows locally +gh act # Run all workflows +gh act -W .github/workflows/ci.yml # Run specific workflow +gh act -j build-test # Run specific job +gh act pull_request # Test PR event +gh act -l # List available workflows + +# Use larger runner image for better compatibility (includes more tools/packages) +gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest +``` + +**Benefits:** +- Catch errors before pushing to GitHub +- Iterate faster on CI fixes +- No need to spam PR with failed CI runs +- Test different event types locally + +**Limitations:** +- Some features may not work identically (secrets, certain GitHub Actions features) +- Larger runner images can be slow to download first time + +### After pushing + +1. Update the PR description with latest changes made +2. Verify CI checks are running successfully +3. Check for any new review comments or feedback +4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) + +## Performance Best Practices + +### Resource Loading + +- Use `preload` for critical CSS/JS with `fetchpriority="high"` +- Add `dns-prefetch` and `preconnect` hints for external resources +- Make resource hints conditional - only add when actually needed +- Avoid render-blocking resources where possible + +### Conditional Loading + +- Check if blocks/features exist before loading their assets +- Use WordPress's `has_block()` function to detect block usage in content +- Check if scripts are enqueued before adding related resources + +## WordPress Specific + +### Hook Priorities + +- Understand hook execution order (wp_enqueue_scripts before wp_head) +- Use appropriate priorities for different types of operations +- Document why specific priorities are chosen + +### Asset Management + +- Use proper asset handles and dependencies +- Defer non-critical JavaScript +- Load CSS appropriately (not everything needs to be async) +- Use manifest files for cache-busting built assets + +## Communication + +- Ask clarifying questions when requirements are ambiguous +- Provide concise explanations (3 sentences or less typically) +- Focus on doing the work, not explaining what you're about to do +- Let the code and commits speak for themselves + +## Bash Scripting + +### Variable References + +- **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety +- **Use UPPERCASE for all variables** - Both script-level and local function variables should be SCREAMING_SNAKE_CASE + +### Formatting + +- **Remove trailing whitespace** - Run `sed -i 's/[[:space:]]*$//' ` on all modified bash scripts before committing +- **Run shfmt** - Run `shfmt -w ` to format bash scripts with consistent indentation (tabs) +- **Run shellcheck** - Always run `shellcheck --severity=style ` to check for issues before committing (matches CI severity) From 9b626a110d7a6f7230c8eaeb519ac377be68c7fd Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 22:57:15 +0000 Subject: [PATCH 02/14] docs: apply remaining improvements to copilot-instructions.md Apply medium-priority fixes and enhancements: Content improvements: - Consolidate lint check sections for clarity - Expand JS/CSS linting with concrete npm examples - Clarify Bash UPPERCASE variable convention (note deviation from standard) - Standardise Bash formatting instructions across sections Navigation enhancements: - Add comprehensive table of contents with subsections - Add quick reference section with common commands - Include linting cheat sheet for all languages - Add branch naming convention reference File grew from 411 to 507 lines with improved organisation and discoverability. All critical and medium-priority issues now resolved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 126 ++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 15 deletions(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index e7f1af0..8409800 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -1,19 +1,34 @@ # Copilot CLI Instructions for Itineris Development +## Table of Contents +- [Critical: Lint Checks Before Pushing](#️-critical-always-run-lint-checks-locally-before-pushing) +- [Language & Spelling](#language--spelling) +- [PHP & WordPress Best Practices](#php--wordpress-best-practices) +- [Git Workflow](#git-workflow) + - [Complete Workflow](#complete-workflow-order-of-operations) + - [Feature Branch Workflow](#feature-branch-workflow) + - [Code Review](#code-review) + - [Merging & Deployment](#merging-to-default-branch) +- [Development Workflow](#development-workflow) + - [Before Committing](#before-committing) + - [Testing GitHub Actions](#testing-github-actions-locally) +- [Performance Best Practices](#performance-best-practices) +- [WordPress Specific](#wordpress-specific) +- [Bash Scripting](#bash-scripting) +- [Communication](#communication) +- [Quick Reference](#quick-reference) + +--- + ## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing **NEVER push to GitHub without running local lint checks first.** -For Bash scripts, ALWAYS run before pushing: +For Bash scripts, ALWAYS run before pushing (see detailed checklist at line 286): ```bash -# 1. Check and remove trailing whitespace -git diff --check && sed -i 's/[[:space:]]*$//' script-name - -# 2. Format with shfmt -shfmt -w script-name && shfmt -d script-name - -# 3. Run ShellCheck at style severity (matches CI) -shellcheck --format=gcc --severity=style script-name +git diff --check # Check trailing whitespace +shfmt -w script-name && shfmt -d script-name # Format +shellcheck --severity=style script-name # Lint ``` For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for specific commands. @@ -277,8 +292,23 @@ See the "Branch Deployment" section above for complete deployment instructions. #### For JavaScript/CSS Changes -1. For JS changes, run linter with auto-fix if available (e.g., `eslint --fix`) -2. For CSS changes, run linter with auto-fix if available (e.g., `stylelint --fix`) +1. For JS changes, run linter with auto-fix if available: + ```bash + # Check package.json for project-specific commands + npm run lint:js + # Or if using eslint directly + npx eslint --fix path/to/file.js + ``` + +2. For CSS changes, run linter with auto-fix if available: + ```bash + # Check package.json for project-specific commands + npm run lint:css + # Or if using stylelint directly + npx stylelint --fix path/to/file.css + ``` + +**Note:** Specific commands vary by project. Check `package.json` scripts section for available lint commands. #### For Bash Script Changes @@ -402,10 +432,76 @@ gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest ### Variable References - **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety -- **Use UPPERCASE for all variables** - Both script-level and local function variables should be SCREAMING_SNAKE_CASE +- **Use UPPERCASE for all variables** - Itineris standard: Both script-level and local function variables should be SCREAMING_SNAKE_CASE (note: this differs from typical Bash convention of lowercase for local variables) ### Formatting -- **Remove trailing whitespace** - Run `sed -i 's/[[:space:]]*$//' ` on all modified bash scripts before committing -- **Run shfmt** - Run `shfmt -w ` to format bash scripts with consistent indentation (tabs) -- **Run shellcheck** - Always run `shellcheck --severity=style ` to check for issues before committing (matches CI severity) +- **Remove trailing whitespace** - Run `git diff --check` to verify, `sed -i 's/[[:space:]]*$//' ` to fix +- **Format with shfmt** - Run `shfmt -w ` for consistent indentation (tabs), `shfmt -d ` to verify +- **Lint with shellcheck** - Run `shellcheck --severity=style ` to match CI severity + +See "Before Committing > For Bash Script Changes" section for complete pre-commit checklist. + +## Quick Reference + +### Common Git Commands +```bash +# Create and push feature branch +git checkout -b clickup// +git push -u origin HEAD + +# Open draft PR +gh pr create --draft --fill + +# Deploy to staging +git push origin HEAD:staging --force + +# Check CI and merge PR +gh pr checks --watch && gh pr merge -m -d --admin +``` + +### Linting Commands + +**Bash:** +```bash +git diff --check # Check trailing whitespace +shfmt -w script.sh && shfmt -d script.sh # Format +shellcheck --severity=style script.sh # Lint +``` + +**PHP:** +```bash +php -l file.php # Syntax check +./vendor/bin/phpcs --standard=phpcs.xml file.php # Lint +./vendor/bin/phpcbf --standard=phpcs.xml file.php # Auto-fix +``` + +**JavaScript/CSS:** +```bash +npm run lint:js # or: npx eslint --fix file.js +npm run lint:css # or: npx stylelint --fix file.css +``` + +### WP CLI Remote Testing +```bash +wp @staging option get home # Test staging +wp @production cache flush # ⚠️ Use with caution +``` + +### PR Comment Management +```bash +# Get PR comments +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Reply and resolve +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_xxx' \ + --message='Fixed in commit abc1234' \ + --resolve +``` + +### Branch Naming Conventions +- ClickUp: `clickup//` +- FreshDesk: `freshdesk//` +- GitHub: `issue//` +- General: `feature/` or `fix/` From 2db809ccffef017947ebc25ff1c80691ade36274 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:03:54 +0000 Subject: [PATCH 03/14] docs: add concrete examples to Performance section Add practical PHP code examples demonstrating: - Conditional preloading with has_block() check - Conditional script enqueuing based on block presence Makes the Performance Best Practices section more actionable with real-world implementation patterns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index 8409800..e77fd5d 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -399,12 +399,32 @@ gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest - Make resource hints conditional - only add when actually needed - Avoid render-blocking resources where possible +**Example:** +```php +// Only preload hero image on pages that use the hero block +add_action('wp_head', function() { + if (has_block('acf/hero-banner')) { + echo ''; + } +}); +``` + ### Conditional Loading - Check if blocks/features exist before loading their assets - Use WordPress's `has_block()` function to detect block usage in content - Check if scripts are enqueued before adding related resources +**Example:** +```php +// Only load animations script when hero block is present +add_action('wp_enqueue_scripts', function() { + if (has_block('acf/hero-banner')) { + wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); + } +}); +``` + ## WordPress Specific ### Hook Priorities From be87abbd3212c478aecbfa16e0198584c587e10b Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:12:43 +0000 Subject: [PATCH 04/14] refactor: split copilot-instructions into focused files Split monolithic 527-line file into 5 focused files for better AI lookup: New structure: - README.md (100 lines) - Main entry, critical rules, navigation - quick-reference.md (170 lines) - Command cheat sheets - git-workflow.md (240 lines) - Git, PR, deployment, code review - code-standards.md (250 lines) - PHP, JS, CSS, Bash standards - tools.md (150 lines) - Scripts, utilities, credentials Benefits: - Faster lookup: Load only relevant file (100-250 lines vs 527) - Better caching: Smaller files fit better in context - Clear scoping: File names indicate exact content - Improved navigation: README with quick links to guides Old file: shell/copilot-instructions.md (527 lines) New directory: shell/copilot-instructions/ (5 files, 910 total lines) Each file is self-contained with cross-references. README serves as main entry point with critical rules always visible. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 527 ------------------ shell/copilot-instructions/README.md | 110 ++++ shell/copilot-instructions/code-standards.md | 235 ++++++++ shell/copilot-instructions/git-workflow.md | 182 ++++++ shell/copilot-instructions/quick-reference.md | 205 +++++++ shell/copilot-instructions/tools.md | 169 ++++++ 6 files changed, 901 insertions(+), 527 deletions(-) delete mode 100644 shell/copilot-instructions.md create mode 100644 shell/copilot-instructions/README.md create mode 100644 shell/copilot-instructions/code-standards.md create mode 100644 shell/copilot-instructions/git-workflow.md create mode 100644 shell/copilot-instructions/quick-reference.md create mode 100644 shell/copilot-instructions/tools.md diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md deleted file mode 100644 index e77fd5d..0000000 --- a/shell/copilot-instructions.md +++ /dev/null @@ -1,527 +0,0 @@ -# Copilot CLI Instructions for Itineris Development - -## Table of Contents -- [Critical: Lint Checks Before Pushing](#️-critical-always-run-lint-checks-locally-before-pushing) -- [Language & Spelling](#language--spelling) -- [PHP & WordPress Best Practices](#php--wordpress-best-practices) -- [Git Workflow](#git-workflow) - - [Complete Workflow](#complete-workflow-order-of-operations) - - [Feature Branch Workflow](#feature-branch-workflow) - - [Code Review](#code-review) - - [Merging & Deployment](#merging-to-default-branch) -- [Development Workflow](#development-workflow) - - [Before Committing](#before-committing) - - [Testing GitHub Actions](#testing-github-actions-locally) -- [Performance Best Practices](#performance-best-practices) -- [WordPress Specific](#wordpress-specific) -- [Bash Scripting](#bash-scripting) -- [Communication](#communication) -- [Quick Reference](#quick-reference) - ---- - -## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing - -**NEVER push to GitHub without running local lint checks first.** - -For Bash scripts, ALWAYS run before pushing (see detailed checklist at line 286): -```bash -git diff --check # Check trailing whitespace -shfmt -w script-name && shfmt -d script-name # Format -shellcheck --severity=style script-name # Lint -``` - -For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for specific commands. - -**Zero tolerance policy**: Fix all issues locally. Do not rely on CI to catch problems. - -**When to run lint checks:** -- Ideally: Before committing (catches issues early) -- Mandatory: Before pushing (prevents CI failures) -- Best practice: Set up pre-commit hooks to automate this - ---- - -## Language & Spelling - -- **Always use British English** for all code, comments, documentation, commit messages, and communication -- Common British English spellings to use: - - "optimise" not "optimize" - - "colour" not "color" - - "behaviour" not "behavior" - - "centre" not "center" - - "licence" (noun) / "license" (verb) - - "analyse" not "analyze" -- This applies to variable names, function names, comments, strings, and all written content - -## PHP & WordPress Best Practices - -### Variable Handling - -- **NEVER use `global $post`** - Always use `get_post()` instead -- **Always check types properly** - Use `instanceof ClassName` instead of truthy checks -- Import classes with `use` statements at the top of files, not Fully Qualified Names (FQNs) inline - -### Code Quality - -- **Remove all trailing whitespace** - Code must be clean -- **Follow WordPress Coding Standards** strictly -- Use `printf()` or `sprintf()` for HTML construction instead of string concatenation with `echo` -- Escape all output appropriately: - - `esc_url()` for URLs - - `esc_attr()` for HTML attributes - - `esc_html()` for HTML content - - Do not mix `esc_xxx` functions with Blade `{{ }}`. Prefer using WordPress functions with unescaped Blade echo `{!! !!}`. - - INCORRECT: `{{ esc_html($var) }}` - - CORRECT: `{!! esc_html($var) !!}` -- Add phpcs ignore comments with explanations when escaping is already handled -- Do not use `get_posts` or `get_terms`. Use their related query classes `WP_Query` and `WP_Term_Query` - -### Code Style - -- Keep lines under 120 characters -- Add trailing commas to multi-line function calls (PHP 8.0+) -- Use descriptive function and variable names to avoid using comments for explanations. -- Use strict types instead of PHPDoc blocks unless required -- Only use PHPDoc blocks if function or variable names are not clear -- Extract duplicate code into helper functions or methods -- Use `PHP_EOL` for line breaks instead of `"\n"` for consistency - -### Error Handling - -- Always validate JSON decoding with `json_last_error()` and type checks -- Check if resources exist before using them -- Add early returns for guard clauses - -### Compiler-Optimised Functions - -- Always import internal PHP functions with `use function` at the top of the file -- Common functions to import: `strlen`, `count`, `is_array`, `in_array`, `array_key_exists`, etc. -- This enables compiler optimisations for better performance -- Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code -- This is a micro-optimisation but matters when functions are called frequently - -## Git Workflow - -### Critical Pre-Push Requirements - -**BEFORE PUSHING TO GITHUB:** -1. **ALWAYS run lint checks locally** - See "Before Committing" section below for specific commands -2. **ALWAYS verify checks pass** - Zero failures allowed -3. **NEVER push without local validation** - CI failures waste time and create noise - -### Branch Protection - -- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) -- **ALWAYS create a feature branch** for any changes -- **ALWAYS create a Pull Request** for review before merging - -### Complete Workflow (Order of Operations) - -When implementing a feature or fix: - -1. **Create feature branch** - If on default branch, create and switch to feature branch first -2. **Push branch immediately** - `git push -u origin ` for visibility -3. **Open draft PR early** - Include implementation plan, links to tickets -4. **Make changes & commit after each phase** - Use conventional commit format -5. **Push after each commit** - Enable real-time review on GitHub -6. **Mark PR as "Ready for Review"** - When all phases complete and tests pass -7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed -8. **Deploy to staging for testing** - `git push origin :staging --force` -9. **Verify changes on staging** - Test that the fix/feature works correctly -10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` -11. **Production deployment** - Happens automatically when default branch is pushed - -**Key points:** -- Always verify on staging BEFORE merging to default branch -- Never merge to default branch without staging verification -- Merging to default branch triggers automatic production deployment - -### Feature Branch Workflow - -When implementing a feature with an implementation plan: - -1. **Check current branch** - If on default branch, create and switch to a feature branch first -2. **Create feature branch** with naming based on ticket source: - - **ClickUp**: `clickup//` (e.g., `clickup/86bzphaee/landing-page-ammends`) - - **FreshDesk**: `freshdesk//` (e.g., `freshdesk/21170/intro-section-image-position`) - - **GitHub Issues**: `issue//` (e.g., `issue/123/fix-navigation-bug`) - - **General** (no ticket): `feature/` or `fix/` (e.g., `feature/add-caching`, `fix/header-spacing`) -3. **Push branch immediately** to GitHub for visibility -4. **Open draft PR early** with: - - Implementation plan in the description - - Clear title describing the feature - - Links to related tickets/documents -5. **Commit after each phase** with conventional commit messages -6. **Push after each commit** for real-time review on GitHub -7. **Update PR description** with progress checkpoints as you go -8. **Mark PR as "Ready for Review"** when all phases complete and tests pass - -### Commits - -- Write clear, descriptive commit messages -- Use conventional commit format when appropriate (feat:, fix:, docs:, test:, refactor:) -- Explain the "why" not just the "what" in commit messages -- Include context about what problem is being solved -- Commit frequently - after each logical phase or component completion -- Push commits regularly so work can be reviewed incrementally - -### Pull Requests - -- Create descriptive PR titles and descriptions -- Include "Overview", "Related Tickets & Documents" sections, "Changes", "Impact", "Testing", "Before/After" -- Prompt user for ClickUp, FreshDesk, GitHub, or Sentry links for the "Related Tickets & Documents" section -- Search for related PRs/issues yourself after asking the user -- Open PRs early as drafts to enable real-time review -- Run linting and tests before pushing - -### Branch Deployment - -- To deploy any branch to an environment: push that branch to the environment branch - - **Staging deployment**: `git push origin :staging --force` - - **Production deployment**: Happens automatically when default branch is pushed -- Works for feature branches, fix branches, or any other branch -- This triggers the CD workflow which deploys to the corresponding environment -- Verify changes on the target environment before proceeding - -### Testing on Remote Environments - -- **WP CLI aliases** are configured in `wp-cli.yml` for remote testing: - - `@staging` - Staging environment - - `@production` - Production environment - - **⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete) -- Use aliases to test WP CLI commands on remote servers: - - Example: `wp @staging option get home` - - Example: `wp @staging cli version` -- Always test on staging after deployment to verify fixes work correctly - -### Code Review - -**Getting PR Comments:** -Use `gh-pr-get-comments` script to retrieve all comments on a PR: -```bash -# Get all comments in pretty format -~/Code/misc/itineris-bin/gh-pr-get-comments - -# Filter by author (e.g., Copilot bot) -~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' - -# Get unresolved review comments only -~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false - -# Get JSON output for parsing -~/Code/misc/itineris-bin/gh-pr-get-comments --format=json -``` - -**Addressing Review Feedback:** -1. Review all comments from code reviewers and validate their accuracy -2. Discuss false-positives or questionable feedback before making changes -3. Don't just make the minimal change - understand and fix the underlying issue -4. Reply to each comment individually in its thread using `gh-pr-reply-to-thread`: - ```bash - # Reply to a review thread (use thread-id from gh-pr-get-comments output) - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' - - # Reply and resolve thread in one command - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' \ - --resolve - - # Resolve thread without replying (e.g., false positive) - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --resolve-only - ``` -5. Include commit links when referencing fixes in replies -6. Resolve threads when issues are fixed, leave unresolved if dismissing/rejecting feedback -7. Re-run linting after addressing comments -8. Push changes promptly to unblock merging -9. After addressing all feedback and pushing, request a new review from Copilot: - ```bash - gh pr edit --add-reviewer @copilot - ``` - -**Important:** Always use the utility scripts (`gh-pr-get-comments` and `gh-pr-reply-to-thread`) instead of raw `gh api` calls for PR comment management. - -### Merging to Default Branch - -- Before merging, ensure the most recent commit was deployed to staging and verified -- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch - - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) - - The `--admin` flag bypasses branch protection rules - - The `-m -d` flags merge and delete the branch after merging -- **Note**: This is only for merging to the default branch, NOT for deploying to staging - -### Deploying to Staging - -See the "Branch Deployment" section above for complete deployment instructions. - -## Development Workflow - -### API Queries - -**GitHub PR Comments:** -- **Get comments**: Use `~/Code/misc/itineris-bin/gh-pr-get-comments` to retrieve PR comments -- **Reply to comments**: Use `~/Code/misc/itineris-bin/gh-pr-reply-to-thread` to reply and resolve threads -- See "Code Review" section for detailed usage examples - -**Task/Ticket Management:** -- **ClickUp**: Use `~/Code/misc/itineris-bin/clickup-get-task` to query ClickUp tasks -- **FreshDesk**: Use `~/Code/misc/itineris-bin/freshdesk-get-ticket` to query FreshDesk tickets -- These scripts handle authentication and API interaction automatically -- Always use these dedicated scripts instead of making direct API calls - -### Accessing Credentials - -- Use 1Password CLI (`op` or `op.exe` on Windows/WSL) to retrieve credentials programmatically -- Example: `op item get "Item Name" --vault "Vault Name" --fields username,password` -- Check project documentation for specific vault and item names - -### Before Committing - -**CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** - -#### For PHP Changes - -1. Run PHP syntax check: `php -l ` -2. Run phpcs linting: `./vendor/bin/phpcs --standard=phpcs.xml ` -3. Auto-fix with phpcbf if needed: `./vendor/bin/phpcbf --standard=phpcs.xml ` - -#### For JavaScript/CSS Changes - -1. For JS changes, run linter with auto-fix if available: - ```bash - # Check package.json for project-specific commands - npm run lint:js - # Or if using eslint directly - npx eslint --fix path/to/file.js - ``` - -2. For CSS changes, run linter with auto-fix if available: - ```bash - # Check package.json for project-specific commands - npm run lint:css - # Or if using stylelint directly - npx stylelint --fix path/to/file.css - ``` - -**Note:** Specific commands vary by project. Check `package.json` scripts section for available lint commands. - -#### For Bash Script Changes - -**MANDATORY: Run ALL these checks before committing ANY Bash script changes:** - -```bash -# 1. Remove trailing whitespace (REQUIRED) -sed -i 's/[[:space:]]*$//' script-name - -# Verify no trailing whitespace in staged changes -git diff --check - -# 2. Format with shfmt (REQUIRED) -shfmt -w script-name - -# Verify formatting is correct -shfmt -d script-name - -# 3. Run ShellCheck with CI-equivalent settings (REQUIRED) -# This must match the severity level used in CI (style severity) -shellcheck --format=gcc --severity=style script-name - -# Or check all modified scripts in your branch -git diff main --name-only --diff-filter=ACMR | \ - xargs shellcheck --format=gcc --severity=style -``` - -**Important ShellCheck Notes:** -- Use `--severity=style` to match CI configuration (not `--severity=warning`) -- Some repositories use differential-shellcheck which checks at "style" level -- SC1091 (sourcing external files) and SC2016 (single quotes) may be acceptable depending on context -- **Zero tolerance policy**: If CI will fail, fix it locally first - -**MANDATORY Pre-Commit Checklist for Bash Scripts:** -- ✅ Trailing whitespace removed (`git diff --check` shows nothing) -- ✅ Script formatted with shfmt (`shfmt -d script-name` shows no diff) -- ✅ ShellCheck passes at style severity (`shellcheck --severity=style`) -- ✅ All variables use `${VAR}` syntax (not `$VAR`) -- ✅ Script tested manually with `--help` flag (if applicable) -- ✅ Documentation updated (README, etc.) - -#### General - -1. Verify all tests pass (if applicable) - -### Testing GitHub Actions Locally - -Before pushing CI workflow changes, test them locally using the [act GitHub CLI extension](https://nektosact.com/installation/gh.html): - -```bash -# Install act as a GitHub CLI extension -gh extension install https://github.com/nektos/gh-act - -# Test workflows locally -gh act # Run all workflows -gh act -W .github/workflows/ci.yml # Run specific workflow -gh act -j build-test # Run specific job -gh act pull_request # Test PR event -gh act -l # List available workflows - -# Use larger runner image for better compatibility (includes more tools/packages) -gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest -``` - -**Benefits:** -- Catch errors before pushing to GitHub -- Iterate faster on CI fixes -- No need to spam PR with failed CI runs -- Test different event types locally - -**Limitations:** -- Some features may not work identically (secrets, certain GitHub Actions features) -- Larger runner images can be slow to download first time - -### After pushing - -1. Update the PR description with latest changes made -2. Verify CI checks are running successfully -3. Check for any new review comments or feedback -4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) - -## Performance Best Practices - -### Resource Loading - -- Use `preload` for critical CSS/JS with `fetchpriority="high"` -- Add `dns-prefetch` and `preconnect` hints for external resources -- Make resource hints conditional - only add when actually needed -- Avoid render-blocking resources where possible - -**Example:** -```php -// Only preload hero image on pages that use the hero block -add_action('wp_head', function() { - if (has_block('acf/hero-banner')) { - echo ''; - } -}); -``` - -### Conditional Loading - -- Check if blocks/features exist before loading their assets -- Use WordPress's `has_block()` function to detect block usage in content -- Check if scripts are enqueued before adding related resources - -**Example:** -```php -// Only load animations script when hero block is present -add_action('wp_enqueue_scripts', function() { - if (has_block('acf/hero-banner')) { - wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); - } -}); -``` - -## WordPress Specific - -### Hook Priorities - -- Understand hook execution order (wp_enqueue_scripts before wp_head) -- Use appropriate priorities for different types of operations -- Document why specific priorities are chosen - -### Asset Management - -- Use proper asset handles and dependencies -- Defer non-critical JavaScript -- Load CSS appropriately (not everything needs to be async) -- Use manifest files for cache-busting built assets - -## Communication - -- Ask clarifying questions when requirements are ambiguous -- Provide concise explanations (3 sentences or less typically) -- Focus on doing the work, not explaining what you're about to do -- Let the code and commits speak for themselves - -## Bash Scripting - -### Variable References - -- **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety -- **Use UPPERCASE for all variables** - Itineris standard: Both script-level and local function variables should be SCREAMING_SNAKE_CASE (note: this differs from typical Bash convention of lowercase for local variables) - -### Formatting - -- **Remove trailing whitespace** - Run `git diff --check` to verify, `sed -i 's/[[:space:]]*$//' ` to fix -- **Format with shfmt** - Run `shfmt -w ` for consistent indentation (tabs), `shfmt -d ` to verify -- **Lint with shellcheck** - Run `shellcheck --severity=style ` to match CI severity - -See "Before Committing > For Bash Script Changes" section for complete pre-commit checklist. - -## Quick Reference - -### Common Git Commands -```bash -# Create and push feature branch -git checkout -b clickup// -git push -u origin HEAD - -# Open draft PR -gh pr create --draft --fill - -# Deploy to staging -git push origin HEAD:staging --force - -# Check CI and merge PR -gh pr checks --watch && gh pr merge -m -d --admin -``` - -### Linting Commands - -**Bash:** -```bash -git diff --check # Check trailing whitespace -shfmt -w script.sh && shfmt -d script.sh # Format -shellcheck --severity=style script.sh # Lint -``` - -**PHP:** -```bash -php -l file.php # Syntax check -./vendor/bin/phpcs --standard=phpcs.xml file.php # Lint -./vendor/bin/phpcbf --standard=phpcs.xml file.php # Auto-fix -``` - -**JavaScript/CSS:** -```bash -npm run lint:js # or: npx eslint --fix file.js -npm run lint:css # or: npx stylelint --fix file.css -``` - -### WP CLI Remote Testing -```bash -wp @staging option get home # Test staging -wp @production cache flush # ⚠️ Use with caution -``` - -### PR Comment Management -```bash -# Get PR comments -~/Code/misc/itineris-bin/gh-pr-get-comments - -# Reply and resolve -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_xxx' \ - --message='Fixed in commit abc1234' \ - --resolve -``` - -### Branch Naming Conventions -- ClickUp: `clickup//` -- FreshDesk: `freshdesk//` -- GitHub: `issue//` -- General: `feature/` or `fix/` diff --git a/shell/copilot-instructions/README.md b/shell/copilot-instructions/README.md new file mode 100644 index 0000000..de67215 --- /dev/null +++ b/shell/copilot-instructions/README.md @@ -0,0 +1,110 @@ +# Copilot CLI Instructions for Itineris Development + +## Quick Navigation +- **[Quick Reference](./quick-reference.md)** - Command cheat sheets for instant copy-paste +- **[Git Workflow](./git-workflow.md)** - Branching, PRs, deployment, code review +- **[Code Standards](./code-standards.md)** - PHP, JavaScript, CSS, Bash coding rules +- **[Tools Reference](./tools.md)** - Scripts, utilities, credentials access + +--- + +## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing + +**NEVER push to GitHub without running local lint checks first.** + +### Quick Lint Commands + +**Bash:** +```bash +git diff --check # Check trailing whitespace +shfmt -w script-name && shfmt -d script-name # Format +shellcheck --severity=style script-name # Lint +``` + +**PHP:** +```bash +php -l file.php # Syntax check +./vendor/bin/phpcs --standard=phpcs.xml file.php # Lint +./vendor/bin/phpcbf --standard=phpcs.xml file.php # Auto-fix +``` + +**JavaScript/CSS:** +```bash +npm run lint:js # or: npx eslint --fix file.js +npm run lint:css # or: npx stylelint --fix file.css +``` + +See [Code Standards](./code-standards.md) for detailed language-specific requirements. + +**Zero tolerance policy**: Fix all issues locally. Do not rely on CI to catch problems. + +**When to run lint checks:** +- Ideally: Before committing (catches issues early) +- Mandatory: Before pushing (prevents CI failures) +- Best practice: Set up pre-commit hooks to automate this + +--- + +## Language & Spelling + +- **Always use British English** for all code, comments, documentation, commit messages, and communication +- Common British English spellings to use: + - "optimise" not "optimize" + - "colour" not "color" + - "behaviour" not "behavior" + - "centre" not "center" + - "licence" (noun) / "license" (verb) + - "analyse" not "analyze" +- This applies to variable names, function names, comments, strings, and all written content + +--- + +## Core Workflow Rules + +### Branch Protection +- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) +- **ALWAYS create a feature branch** for any changes +- **ALWAYS create a Pull Request** for review before merging + +### Essential Git Commands +```bash +# Create and push feature branch +git checkout -b clickup// +git push -u origin HEAD + +# Deploy to staging +git push origin HEAD:staging --force + +# Check CI and merge PR +gh pr checks --watch && gh pr merge -m -d --admin +``` + +See [Git Workflow](./git-workflow.md) for complete process. + +--- + +## Communication + +- Ask clarifying questions when requirements are ambiguous +- Provide concise explanations (3 sentences or less typically) +- Focus on doing the work, not explaining what you're about to do +- Let the code and commits speak for themselves + +--- + +## When to Use Which Guide + +**Starting a new task or feature?** +→ Read [Git Workflow](./git-workflow.md) for branch creation and PR process + +**Writing or fixing code?** +→ Check [Code Standards](./code-standards.md) for language-specific rules + +**Need a specific command?** +→ Check [Quick Reference](./quick-reference.md) for copy-paste ready commands + +**Using a script or tool?** +→ Check [Tools Reference](./tools.md) for paths and usage examples + +**Before committing or pushing?** +→ Run lint checks (see Critical section above) + review [Code Standards](./code-standards.md) diff --git a/shell/copilot-instructions/code-standards.md b/shell/copilot-instructions/code-standards.md new file mode 100644 index 0000000..3420b64 --- /dev/null +++ b/shell/copilot-instructions/code-standards.md @@ -0,0 +1,235 @@ +# Code Standards + +Language-specific coding standards and linting requirements for Itineris projects. + +## Language & Spelling + +- **Always use British English** for all code, comments, documentation, commit messages, and communication +- Common British English spellings to use: + - "optimise" not "optimize" + - "colour" not "color" + - "behaviour" not "behavior" + - "centre" not "center" + - "licence" (noun) / "license" (verb) + - "analyse" not "analyze" +- This applies to variable names, function names, comments, strings, and all written content + +--- + +## PHP & WordPress Best Practices + +### Variable Handling + +- **NEVER use `global $post`** - Always use `get_post()` instead +- **Always check types properly** - Use `instanceof ClassName` instead of truthy checks +- Import classes with `use` statements at the top of files, not Fully Qualified Names (FQNs) inline + +### Code Quality + +- **Remove all trailing whitespace** - Code must be clean +- **Follow WordPress Coding Standards** strictly +- Use `printf()` or `sprintf()` for HTML construction instead of string concatenation with `echo` +- Escape all output appropriately: + - `esc_url()` for URLs + - `esc_attr()` for HTML attributes + - `esc_html()` for HTML content + - Do not mix `esc_xxx` functions with Blade `{{ }}`. Prefer using WordPress functions with unescaped Blade echo `{!! !!}`. + - INCORRECT: `{{ esc_html($var) }}` + - CORRECT: `{!! esc_html($var) !!}` +- Add phpcs ignore comments with explanations when escaping is already handled +- Do not use `get_posts` or `get_terms`. Use their related query classes `WP_Query` and `WP_Term_Query` + +### Code Style + +- Keep lines under 120 characters +- Add trailing commas to multi-line function calls (PHP 8.0+) +- Use descriptive function and variable names to avoid using comments for explanations. +- Use strict types instead of PHPDoc blocks unless required +- Only use PHPDoc blocks if function or variable names are not clear +- Extract duplicate code into helper functions or methods +- Use `PHP_EOL` for line breaks instead of `"\n"` for consistency + +### Error Handling + +- Always validate JSON decoding with `json_last_error()` and type checks +- Check if resources exist before using them +- Add early returns for guard clauses + +### Compiler-Optimised Functions + +- Always import internal PHP functions with `use function` at the top of the file +- Common functions to import: `strlen`, `count`, `is_array`, `in_array`, `array_key_exists`, etc. +- This enables compiler optimisations for better performance +- Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code +- This is a micro-optimisation but matters when functions are called frequently + +--- + +## JavaScript & CSS Standards + +### JavaScript + +- Run linter with auto-fix before committing +- Check `package.json` for project-specific lint commands +- Common commands: + ```bash + npm run lint:js + npx eslint --fix path/to/file.js + ``` + +### CSS + +- Run linter with auto-fix before committing +- Check `package.json` for project-specific lint commands +- Common commands: + ```bash + npm run lint:css + npx stylelint --fix path/to/file.css + ``` + +**Note:** Specific commands vary by project. Always check `package.json` scripts section for available lint commands. + +--- + +## Bash Scripting Standards + +### Variable References + +- **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety +- **Use UPPERCASE for all variables** - Itineris standard: Both script-level and local function variables should be SCREAMING_SNAKE_CASE (note: this differs from typical Bash convention of lowercase for local variables) + +### Formatting Requirements + +- **Remove trailing whitespace** - Run `git diff --check` to verify, `sed -i 's/[[:space:]]*$//' ` to fix +- **Format with shfmt** - Run `shfmt -w ` for consistent indentation (tabs), `shfmt -d ` to verify +- **Lint with shellcheck** - Run `shellcheck --severity=style ` to match CI severity + +--- + +## Before Committing + +**CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** + +### PHP Changes + +1. Run PHP syntax check: `php -l ` +2. Run phpcs linting: `./vendor/bin/phpcs --standard=phpcs.xml ` +3. Auto-fix with phpcbf if needed: `./vendor/bin/phpcbf --standard=phpcs.xml ` + +### JavaScript/CSS Changes + +1. For JS changes: + ```bash + # Check package.json for project-specific commands + npm run lint:js + # Or if using eslint directly + npx eslint --fix path/to/file.js + ``` + +2. For CSS changes: + ```bash + # Check package.json for project-specific commands + npm run lint:css + # Or if using stylelint directly + npx stylelint --fix path/to/file.css + ``` + +**Note:** Specific commands vary by project. Check `package.json` scripts section for available lint commands. + +### Bash Script Changes + +**MANDATORY: Run ALL these checks before committing ANY Bash script changes:** + +```bash +# 1. Remove trailing whitespace (REQUIRED) +sed -i 's/[[:space:]]*$//' script-name + +# Verify no trailing whitespace in staged changes +git diff --check + +# 2. Format with shfmt (REQUIRED) +shfmt -w script-name + +# Verify formatting is correct +shfmt -d script-name + +# 3. Run ShellCheck with CI-equivalent settings (REQUIRED) +# This must match the severity level used in CI (style severity) +shellcheck --format=gcc --severity=style script-name + +# Or check all modified scripts in your branch +git diff main --name-only --diff-filter=ACMR | \ + xargs shellcheck --format=gcc --severity=style +``` + +**Important ShellCheck Notes:** +- Use `--severity=style` to match CI configuration (not `--severity=warning`) +- Some repositories use differential-shellcheck which checks at "style" level +- SC1091 (sourcing external files) and SC2016 (single quotes) may be acceptable depending on context +- **Zero tolerance policy**: If CI will fail, fix it locally first + +**MANDATORY Pre-Commit Checklist for Bash Scripts:** +- ✅ Trailing whitespace removed (`git diff --check` shows nothing) +- ✅ Script formatted with shfmt (`shfmt -d script-name` shows no diff) +- ✅ ShellCheck passes at style severity (`shellcheck --severity=style`) +- ✅ All variables use `${VAR}` syntax (not `$VAR`) +- ✅ Script tested manually with `--help` flag (if applicable) +- ✅ Documentation updated (README, etc.) + +### General + +1. Verify all tests pass (if applicable) + +--- + +## Performance Best Practices + +### Resource Loading + +- Use `preload` for critical CSS/JS with `fetchpriority="high"` +- Add `dns-prefetch` and `preconnect` hints for external resources +- Make resource hints conditional - only add when actually needed +- Avoid render-blocking resources where possible + +**Example:** +```php +// Only preload hero image on pages that use the hero block +add_action('wp_head', function() { + if (has_block('acf/hero-banner')) { + echo ''; + } +}); +``` + +### Conditional Loading + +- Check if blocks/features exist before loading their assets +- Use WordPress's `has_block()` function to detect block usage in content +- Check if scripts are enqueued before adding related resources + +**Example:** +```php +// Only load animations script when hero block is present +add_action('wp_enqueue_scripts', function() { + if (has_block('acf/hero-banner')) { + wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); + } +}); +``` + +--- + +## WordPress Specific + +### Hook Priorities + +- Understand hook execution order (wp_enqueue_scripts before wp_head) +- Use appropriate priorities for different types of operations +- Document why specific priorities are chosen + +### Asset Management + +- Use proper asset handles and dependencies +- Defer non-critical JavaScript +- Load CSS appropriately (not everything needs to be async) +- Use manifest files for cache-busting built assets diff --git a/shell/copilot-instructions/git-workflow.md b/shell/copilot-instructions/git-workflow.md new file mode 100644 index 0000000..51816e5 --- /dev/null +++ b/shell/copilot-instructions/git-workflow.md @@ -0,0 +1,182 @@ +# Git Workflow + +Complete guide to branching, pull requests, code review, and deployment. + +## Critical Pre-Push Requirements + +**BEFORE PUSHING TO GITHUB:** +1. **ALWAYS run lint checks locally** - See [Code Standards](./code-standards.md) for language-specific commands +2. **ALWAYS verify checks pass** - Zero failures allowed +3. **NEVER push without local validation** - CI failures waste time and create noise + +## Branch Protection + +- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) +- **ALWAYS create a feature branch** for any changes +- **ALWAYS create a Pull Request** for review before merging + +--- + +## Complete Workflow (Order of Operations) + +When implementing a feature or fix: + +1. **Create feature branch** - If on default branch, create and switch to feature branch first +2. **Push branch immediately** - `git push -u origin ` for visibility +3. **Open draft PR early** - Include implementation plan, links to tickets +4. **Make changes & commit after each phase** - Use conventional commit format +5. **Push after each commit** - Enable real-time review on GitHub +6. **Mark PR as "Ready for Review"** - When all phases complete and tests pass +7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed +8. **Deploy to staging for testing** - `git push origin :staging --force` +9. **Verify changes on staging** - Test that the fix/feature works correctly +10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` +11. **Production deployment** - Happens automatically when default branch is pushed + +**Key points:** +- Always verify on staging BEFORE merging to default branch +- Never merge to default branch without staging verification +- Merging to default branch triggers automatic production deployment + +--- + +## Feature Branch Workflow + +When implementing a feature with an implementation plan: + +1. **Check current branch** - If on default branch, create and switch to a feature branch first +2. **Create feature branch** with naming based on ticket source: + - **ClickUp**: `clickup//` (e.g., `clickup/86bzphaee/landing-page-ammends`) + - **FreshDesk**: `freshdesk//` (e.g., `freshdesk/21170/intro-section-image-position`) + - **GitHub Issues**: `issue//` (e.g., `issue/123/fix-navigation-bug`) + - **General** (no ticket): `feature/` or `fix/` (e.g., `feature/add-caching`, `fix/header-spacing`) +3. **Push branch immediately** to GitHub for visibility +4. **Open draft PR early** with: + - Implementation plan in the description + - Clear title describing the feature + - Links to related tickets/documents +5. **Commit after each phase** with conventional commit messages +6. **Push after each commit** for real-time review on GitHub +7. **Update PR description** with progress checkpoints as you go +8. **Mark PR as "Ready for Review"** when all phases complete and tests pass + +--- + +## Commits + +- Write clear, descriptive commit messages +- Use conventional commit format when appropriate (feat:, fix:, docs:, test:, refactor:) +- Explain the "why" not just the "what" in commit messages +- Include context about what problem is being solved +- Commit frequently - after each logical phase or component completion +- Push commits regularly so work can be reviewed incrementally + +--- + +## Pull Requests + +- Create descriptive PR titles and descriptions +- Include "Overview", "Related Tickets & Documents" sections, "Changes", "Impact", "Testing", "Before/After" +- Prompt user for ClickUp, FreshDesk, GitHub, or Sentry links for the "Related Tickets & Documents" section +- Search for related PRs/issues yourself after asking the user +- Open PRs early as drafts to enable real-time review +- Run linting and tests before pushing + +--- + +## Branch Deployment + +- To deploy any branch to an environment: push that branch to the environment branch + - **Staging deployment**: `git push origin :staging --force` + - **Production deployment**: Happens automatically when default branch is pushed +- Works for feature branches, fix branches, or any other branch +- This triggers the CD workflow which deploys to the corresponding environment +- Verify changes on the target environment before proceeding + +--- + +## Testing on Remote Environments + +- **WP CLI aliases** are configured in `wp-cli.yml` for remote testing: + - `@staging` - Staging environment + - `@production` - Production environment + - **⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete) +- Use aliases to test WP CLI commands on remote servers: + - Example: `wp @staging option get home` + - Example: `wp @staging cli version` +- Always test on staging after deployment to verify fixes work correctly + +--- + +## Code Review + +### Getting PR Comments + +Use `gh-pr-get-comments` script to retrieve all comments on a PR: +```bash +# Get all comments in pretty format +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author (e.g., Copilot bot) +~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' + +# Get unresolved review comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# Get JSON output for parsing +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +### Addressing Review Feedback + +1. Review all comments from code reviewers and validate their accuracy +2. Discuss false-positives or questionable feedback before making changes +3. Don't just make the minimal change - understand and fix the underlying issue +4. Reply to each comment individually in its thread using `gh-pr-reply-to-thread`: + ```bash + # Reply to a review thread (use thread-id from gh-pr-get-comments output) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' + + # Reply and resolve thread in one command + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + + # Resolve thread without replying (e.g., false positive) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only + ``` +5. Include commit links when referencing fixes in replies +6. Resolve threads when issues are fixed, leave unresolved if dismissing/rejecting feedback +7. Re-run linting after addressing comments +8. Push changes promptly to unblock merging +9. After addressing all feedback and pushing, request a new review from Copilot: + ```bash + gh pr edit --add-reviewer @copilot + ``` + +**Important:** Always use the utility scripts (`gh-pr-get-comments` and `gh-pr-reply-to-thread`) instead of raw `gh api` calls for PR comment management. + +--- + +## Merging to Default Branch + +- Before merging, ensure the most recent commit was deployed to staging and verified +- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch + - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) + - The `--admin` flag bypasses branch protection rules + - The `-m -d` flags merge and delete the branch after merging +- **Note**: This is only for merging to the default branch, NOT for deploying to staging + +--- + +## After Pushing + +1. Update the PR description with latest changes made +2. Verify CI checks are running successfully +3. Check for any new review comments or feedback +4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) diff --git a/shell/copilot-instructions/quick-reference.md b/shell/copilot-instructions/quick-reference.md new file mode 100644 index 0000000..65b829d --- /dev/null +++ b/shell/copilot-instructions/quick-reference.md @@ -0,0 +1,205 @@ +# Quick Reference + +Fast command lookup for common tasks. See main guides for detailed explanations. + +## Git Commands + +### Branch Creation & Push +```bash +# Create feature branch based on ticket source +git checkout -b clickup// # ClickUp +git checkout -b freshdesk// # FreshDesk +git checkout -b issue// # GitHub Issues +git checkout -b feature/ # No ticket + +# Push and track +git push -u origin HEAD +``` + +### Pull Requests +```bash +# Open draft PR +gh pr create --draft --fill + +# Check CI status and merge +gh pr checks --watch && gh pr merge -m -d --admin + +# Or use alias +gh_check_merge --admin +``` + +### Deployment +```bash +# Deploy any branch to staging +git push origin :staging --force + +# Deploy to production (automatic on default branch merge) +# Happens automatically when PR is merged to main/master +``` + +--- + +## Linting Commands + +### Bash Scripts +```bash +# Check trailing whitespace +git diff --check + +# Remove trailing whitespace +sed -i 's/[[:space:]]*$//' script.sh + +# Format with shfmt +shfmt -w script.sh # Apply formatting +shfmt -d script.sh # Verify formatting + +# Lint with shellcheck +shellcheck --severity=style script.sh + +# Check all modified scripts in branch +git diff main --name-only --diff-filter=ACMR | \ + xargs shellcheck --format=gcc --severity=style +``` + +### PHP +```bash +# Syntax check +php -l file.php + +# Lint +./vendor/bin/phpcs --standard=phpcs.xml file.php + +# Auto-fix +./vendor/bin/phpcbf --standard=phpcs.xml file.php +``` + +### JavaScript +```bash +# Project-specific (check package.json) +npm run lint:js + +# Or using eslint directly +npx eslint --fix path/to/file.js +``` + +### CSS +```bash +# Project-specific (check package.json) +npm run lint:css + +# Or using stylelint directly +npx stylelint --fix path/to/file.css +``` + +--- + +## WP CLI Remote Testing + +```bash +# Staging environment +wp @staging option get home +wp @staging cli version +wp @staging cache flush + +# Production environment (⚠️ USE WITH CAUTION) +wp @production option get home # Read-only: safe +wp @production cache flush # Write operation: be careful +``` + +**Warning:** Prefer read-only commands (get, list) on @production. Write operations (set, update, delete) should be rare and deliberate. + +--- + +## PR Comment Management + +### Get Comments +```bash +# All comments in pretty format +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author +~/Code/misc/itineris-bin/gh-pr-get-comments \ + --author='github-advanced-security[bot]' + +# Unresolved comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# JSON output +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +### Reply to Comments +```bash +# Reply to thread +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' + +# Reply and resolve +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + +# Resolve without reply +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only + +# Request new review after fixes +gh pr edit --add-reviewer @copilot +``` + +--- + +## Task/Ticket Management + +```bash +# ClickUp +~/Code/misc/itineris-bin/clickup-get-task + +# FreshDesk +~/Code/misc/itineris-bin/freshdesk-get-ticket +``` + +--- + +## GitHub Actions Testing + +```bash +# Install act (one-time) +gh extension install https://github.com/nektos/gh-act + +# Test workflows locally +gh act # Run all workflows +gh act -W .github/workflows/ci.yml # Specific workflow +gh act -j build-test # Specific job +gh act pull_request # Test PR event +gh act -l # List workflows + +# Use larger runner image +gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest +``` + +--- + +## Credentials Access + +```bash +# 1Password CLI +op item get "Item Name" --vault "Vault Name" --fields username,password + +# Or on Windows/WSL +op.exe item get "Item Name" --vault "Vault Name" --fields username,password +``` + +--- + +## Branch Naming Conventions + +| Ticket Source | Format | Example | +|--------------|--------|---------| +| ClickUp | `clickup//` | `clickup/86bzphaee/landing-page-ammends` | +| FreshDesk | `freshdesk//` | `freshdesk/21170/intro-section-image-position` | +| GitHub Issues | `issue//` | `issue/123/fix-navigation-bug` | +| No ticket | `feature/` or `fix/` | `feature/add-caching`, `fix/header-spacing` | diff --git a/shell/copilot-instructions/tools.md b/shell/copilot-instructions/tools.md new file mode 100644 index 0000000..49224f2 --- /dev/null +++ b/shell/copilot-instructions/tools.md @@ -0,0 +1,169 @@ +# Tools Reference + +Scripts, utilities, and tools available for Itineris development workflows. + +## GitHub PR Comment Management + +### Get PR Comments + +Use `gh-pr-get-comments` script to retrieve all comments on a PR: + +```bash +# Get all comments in pretty format +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author (e.g., Copilot bot) +~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' + +# Get unresolved review comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# Get JSON output for parsing +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +### Reply to PR Comments + +Use `gh-pr-reply-to-thread` script to reply and resolve review threads: + +```bash +# Reply to a review thread (use thread-id from gh-pr-get-comments output) +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' + +# Reply and resolve thread in one command +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + +# Resolve thread without replying (e.g., false positive) +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only +``` + +**Important:** Always use these utility scripts instead of raw `gh api` calls for PR comment management. + +--- + +## Task & Ticket Management + +### ClickUp + +Query ClickUp tasks programmatically: + +```bash +~/Code/misc/itineris-bin/clickup-get-task +``` + +### FreshDesk + +Query FreshDesk tickets programmatically: + +```bash +~/Code/misc/itineris-bin/freshdesk-get-ticket +``` + +**Note:** These scripts handle authentication and API interaction automatically. Always use these dedicated scripts instead of making direct API calls. + +--- + +## Credentials Access + +### 1Password CLI + +Use 1Password CLI to retrieve credentials programmatically: + +```bash +# Standard usage +op item get "Item Name" --vault "Vault Name" --fields username,password + +# On Windows/WSL +op.exe item get "Item Name" --vault "Vault Name" --fields username,password +``` + +**Note:** Check project documentation for specific vault and item names for each project. + +--- + +## GitHub Actions Testing + +### Testing Workflows Locally with act + +Before pushing CI workflow changes, test them locally using the [act GitHub CLI extension](https://nektosact.com/installation/gh.html): + +```bash +# Install act as a GitHub CLI extension (one-time) +gh extension install https://github.com/nektos/gh-act + +# Test workflows locally +gh act # Run all workflows +gh act -W .github/workflows/ci.yml # Run specific workflow +gh act -j build-test # Run specific job +gh act pull_request # Test PR event +gh act -l # List available workflows + +# Use larger runner image for better compatibility (includes more tools/packages) +gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest +``` + +**Benefits:** +- Catch errors before pushing to GitHub +- Iterate faster on CI fixes +- No need to spam PR with failed CI runs +- Test different event types locally + +**Limitations:** +- Some features may not work identically (secrets, certain GitHub Actions features) +- Larger runner images can be slow to download first time + +--- + +## WP CLI Remote Testing + +### Configured Aliases + +WP CLI aliases are configured in `wp-cli.yml` for remote testing: +- `@staging` - Staging environment +- `@production` - Production environment + +### Usage + +```bash +# Staging environment (safe for testing) +wp @staging option get home +wp @staging cli version +wp @staging cache flush + +# Production environment (⚠️ USE WITH CAUTION) +wp @production option get home # Read-only: safe +wp @production cache flush # Write operation: be careful +``` + +**⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete). + +### Testing After Deployment + +Always test on staging after deployment to verify fixes work correctly: + +```bash +# Deploy to staging +git push origin HEAD:staging --force + +# Test the fix +wp @staging option get home +wp @staging cache flush +``` + +--- + +## Quick Command Reference + +See [Quick Reference](./quick-reference.md) for a comprehensive command cheat sheet including: +- Git commands +- Linting commands +- PR management +- Branch naming conventions +- Deployment commands From 1959deb20624501e8205e7c032f9e49ea64ac4ab Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:19:56 +0000 Subject: [PATCH 05/14] docs: clarify PR comment workflow sequence Make it explicit that PR comment management is a two-step process: 1. Get comments first (to retrieve thread IDs) 2. Use those thread IDs to reply/resolve Changes: - Add 'Workflow Overview' section in tools.md - Add step numbers and explanatory notes - Clarify that thread-id comes from step 1 output - Add workflow summary to quick-reference.md This prevents confusion about where thread IDs come from and makes the command sequence clear. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions/quick-reference.md | 8 +++++--- shell/copilot-instructions/tools.md | 17 ++++++++++++----- shell/functions | 3 ++- terminals/alacritty.toml | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/shell/copilot-instructions/quick-reference.md b/shell/copilot-instructions/quick-reference.md index 65b829d..6596710 100644 --- a/shell/copilot-instructions/quick-reference.md +++ b/shell/copilot-instructions/quick-reference.md @@ -112,9 +112,11 @@ wp @production cache flush # Write operation: be careful ## PR Comment Management +**Workflow:** Get comments first (to find thread IDs), then reply/resolve using those IDs. + ### Get Comments ```bash -# All comments in pretty format +# Step 1: Get all comments (includes thread IDs in output) ~/Code/misc/itineris-bin/gh-pr-get-comments # Filter by author @@ -130,9 +132,9 @@ wp @production cache flush # Write operation: be careful ### Reply to Comments ```bash -# Reply to thread +# Step 2: Reply using thread-id from step 1 ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ + --thread-id='PRRT_xxx' \ --message='Fixed in commit abc1234' # Reply and resolve diff --git a/shell/copilot-instructions/tools.md b/shell/copilot-instructions/tools.md index 49224f2..cd19055 100644 --- a/shell/copilot-instructions/tools.md +++ b/shell/copilot-instructions/tools.md @@ -4,12 +4,17 @@ Scripts, utilities, and tools available for Itineris development workflows. ## GitHub PR Comment Management -### Get PR Comments +### Workflow Overview -Use `gh-pr-get-comments` script to retrieve all comments on a PR: +1. **First:** Get PR comments to see thread IDs +2. **Then:** Reply/resolve specific threads using the thread IDs from step 1 + +### Step 1: Get PR Comments + +Use `gh-pr-get-comments` to retrieve all comments and their thread IDs: ```bash -# Get all comments in pretty format +# Get all comments in pretty format (includes thread IDs) ~/Code/misc/itineris-bin/gh-pr-get-comments # Filter by author (e.g., Copilot bot) @@ -22,9 +27,11 @@ Use `gh-pr-get-comments` script to retrieve all comments on a PR: ~/Code/misc/itineris-bin/gh-pr-get-comments --format=json ``` -### Reply to PR Comments +**Note:** The output includes `thread-id` values (e.g., `PRRT_kwDOABCDEF`) which you need for the next step. + +### Step 2: Reply to PR Comments -Use `gh-pr-reply-to-thread` script to reply and resolve review threads: +Use `gh-pr-reply-to-thread` with the thread-id from step 1: ```bash # Reply to a review thread (use thread-id from gh-pr-get-comments output) diff --git a/shell/functions b/shell/functions index 7f3cf23..dfa5d1a 100644 --- a/shell/functions +++ b/shell/functions @@ -203,7 +203,8 @@ install_wsl_packages() { install_git_delta # ensure fd is available ln -sf "$(which fdfind)" ~/.local/bin/fd - + # ensure bat is available + ln -sf "$(which batcat)" ~/.local/bin/bat # Generate the `rg` zsh completion file for zinit. rg --generate=complete-zsh >~/.zinit/completions/_rg } diff --git a/terminals/alacritty.toml b/terminals/alacritty.toml index 56e8ca5..4c40d16 100644 --- a/terminals/alacritty.toml +++ b/terminals/alacritty.toml @@ -50,7 +50,7 @@ decorations = "None" decorations_theme_variant = "Dark" dynamic_padding = true dynamic_title = true -opacity = 0.75 +opacity = 1 startup_mode = "Maximized" [window.padding] From 4ad26dad3a73050622bfcce21c861a40fb13da4e Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:36:28 +0000 Subject: [PATCH 06/14] refactor: merge split instructions back into single file Copilot CLI only loads the single file at ~/.copilot/copilot-instructions.md and does not follow relative links to other files. The 5-file split broke the instructions - only README.md was loaded, missing all the detailed commands in other files. This reverts to a single comprehensive file containing all content from: - README.md (critical rules, navigation) - quick-reference.md (command cheat sheets) - git-workflow.md (branching, PRs, deployment) - code-standards.md (language-specific rules) - tools.md (scripts, utilities) All improvements from the refactor are preserved: - Fixed critical issues (line refs, commands, flags) - Clearer sections and organization - Concrete examples - Better formatting Symlink updated: ~/.copilot/copilot-instructions.md -> ~/.dotfiles/shell/copilot-instructions.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 545 ++++++++++++++++++ shell/copilot-instructions/README.md | 110 ---- shell/copilot-instructions/code-standards.md | 235 -------- shell/copilot-instructions/git-workflow.md | 182 ------ shell/copilot-instructions/quick-reference.md | 207 ------- shell/copilot-instructions/tools.md | 176 ------ 6 files changed, 545 insertions(+), 910 deletions(-) create mode 100644 shell/copilot-instructions.md delete mode 100644 shell/copilot-instructions/README.md delete mode 100644 shell/copilot-instructions/code-standards.md delete mode 100644 shell/copilot-instructions/git-workflow.md delete mode 100644 shell/copilot-instructions/quick-reference.md delete mode 100644 shell/copilot-instructions/tools.md diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md new file mode 100644 index 0000000..20a9e36 --- /dev/null +++ b/shell/copilot-instructions.md @@ -0,0 +1,545 @@ +# Copilot CLI Instructions for Itineris Development + +## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing + +**NEVER push to GitHub without running local lint checks first.** + +For Bash scripts, ALWAYS run before pushing: +```bash +# 1. Check and remove trailing whitespace +git diff --check && sed -i 's/[[:space:]]*$//' script-name + +# 2. Format with shfmt +shfmt -w script-name && shfmt -d script-name + +# 3. Run ShellCheck at style severity (matches CI) +shellcheck --format=gcc --severity=style script-name +``` + +For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for specific commands. + +**Zero tolerance policy**: Fix all issues locally. Do not rely on CI to catch problems. + +**When to run lint checks:** +- Ideally: Before committing (catches issues early) +- Mandatory: Before pushing (prevents CI failures) +- Best practice: Set up pre-commit hooks to automate this + +--- + +## Language & Spelling + +- **Always use British English** for all code, comments, documentation, commit messages, and communication +- Common British English spellings to use: + - "optimise" not "optimize" + - "colour" not "color" + - "behaviour" not "behavior" + - "centre" not "center" + - "licence" (noun) / "license" (verb) + - "analyse" not "analyze" +- This applies to variable names, function names, comments, strings, and all written content + +## PHP & WordPress Best Practices + +### Variable Handling + +- **NEVER use `global $post`** - Always use `get_post()` instead +- **Always check types properly** - Use `instanceof ClassName` instead of truthy checks +- Import classes with `use` statements at the top of files, not Fully Qualified Names (FQNs) inline + +### Code Quality + +- **Remove all trailing whitespace** - Code must be clean +- **Follow WordPress Coding Standards** strictly +- Use `printf()` or `sprintf()` for HTML construction instead of string concatenation with `echo` +- Escape all output appropriately: + - `esc_url()` for URLs + - `esc_attr()` for HTML attributes + - `esc_html()` for HTML content + - Do not mix `esc_xxx` functions with Blade `{{ }}`. Prefer using WordPress functions with unescaped Blade echo `{!! !!}`. + - INCORRECT: `{{ esc_html($var) }}` + - CORRECT: `{!! esc_html($var) !!}` +- Add phpcs ignore comments with explanations when escaping is already handled +- Do not use `get_posts` or `get_terms`. Use their related query classes `WP_Query` and `WP_Term_Query` + +### Code Style + +- Keep lines under 120 characters +- Add trailing commas to multi-line function calls (PHP 8.0+) +- Use descriptive function and variable names to avoid using comments for explanations. +- Use strict types instead of PHPDoc blocks unless required +- Only use PHPDoc blocks if function or variable names are not clear +- Extract duplicate code into helper functions or methods +- Use `PHP_EOL` for line breaks instead of `"\n"` for consistency + +### Error Handling + +- Always validate JSON decoding with `json_last_error()` and type checks +- Check if resources exist before using them +- Add early returns for guard clauses + +### Compiler-Optimised Functions + +- Always import internal PHP functions with `use function` at the top of the file +- Common functions to import: `strlen`, `count`, `is_array`, `in_array`, `array_key_exists`, etc. +- This enables compiler optimisations for better performance +- Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code +- This is a micro-optimisation but matters when functions are called frequently + +## Git Workflow + +### Critical Pre-Push Requirements + +**BEFORE PUSHING TO GITHUB:** +1. **ALWAYS run lint checks locally** - See "Before Committing" section for language-specific commands +2. **ALWAYS verify checks pass** - Zero failures allowed +3. **NEVER push without local validation** - CI failures waste time and create noise + +### Branch Protection + +- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) +- **ALWAYS create a feature branch** for any changes +- **ALWAYS create a Pull Request** for review before merging + +### Complete Workflow (Order of Operations) + +When implementing a feature or fix: + +1. **Create feature branch** - If on default branch, create and switch to feature branch first +2. **Push branch immediately** - `git push -u origin ` for visibility +3. **Open draft PR early** - Include implementation plan, links to tickets +4. **Make changes & commit after each phase** - Use conventional commit format +5. **Push after each commit** - Enable real-time review on GitHub +6. **Mark PR as "Ready for Review"** - When all phases complete and tests pass +7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed +8. **Deploy to staging for testing** - `git push origin :staging --force` +9. **Verify changes on staging** - Test that the fix/feature works correctly +10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` +11. **Production deployment** - Happens automatically when default branch is pushed + +**Key points:** +- Always verify on staging BEFORE merging to default branch +- Never merge to default branch without staging verification +- Merging to default branch triggers automatic production deployment + +### Feature Branch Workflow + +When implementing a feature with an implementation plan: + +1. **Check current branch** - If on default branch, create and switch to a feature branch first +2. **Create feature branch** with naming based on ticket source: + - **ClickUp**: `clickup//` (e.g., `clickup/86bzphaee/landing-page-ammends`) + - **FreshDesk**: `freshdesk//` (e.g., `freshdesk/21170/intro-section-image-position`) + - **GitHub Issues**: `issue//` (e.g., `issue/123/fix-navigation-bug`) + - **General** (no ticket): `feature/` or `fix/` (e.g., `feature/add-caching`, `fix/header-spacing`) +3. **Push branch immediately** to GitHub for visibility +4. **Open draft PR early** with: + - Implementation plan in the description + - Clear title describing the feature + - Links to related tickets/documents +5. **Commit after each phase** with conventional commit messages +6. **Push after each commit** for real-time review on GitHub +7. **Update PR description** with progress checkpoints as you go +8. **Mark PR as "Ready for Review"** when all phases complete and tests pass + +### Commits + +- Write clear, descriptive commit messages +- Use conventional commit format when appropriate (feat:, fix:, docs:, test:, refactor:) +- Explain the "why" not just the "what" in commit messages +- Include context about what problem is being solved +- Commit frequently - after each logical phase or component completion +- Push commits regularly so work can be reviewed incrementally + +### Pull Requests + +- Create descriptive PR titles and descriptions +- Include "Overview", "Related Tickets & Documents" sections, "Changes", "Impact", "Testing", "Before/After" +- Prompt user for ClickUp, FreshDesk, GitHub, or Sentry links for the "Related Tickets & Documents" section +- Search for related PRs/issues yourself after asking the user +- Open PRs early as drafts to enable real-time review +- Run linting and tests before pushing + +### Branch Deployment + +- To deploy any branch to an environment: push that branch to the environment branch + - **Staging deployment**: `git push origin :staging --force` + - **Production deployment**: Happens automatically when default branch is pushed +- Works for feature branches, fix branches, or any other branch +- This triggers the CD workflow which deploys to the corresponding environment +- Verify changes on the target environment before proceeding + +### Testing on Remote Environments + +- **WP CLI aliases** are configured in `wp-cli.yml` for remote testing: + - `@staging` - Staging environment + - `@production` - Production environment + - **⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete) +- Use aliases to test WP CLI commands on remote servers: + - Example: `wp @staging option get home` + - Example: `wp @staging cli version` +- Always test on staging after deployment to verify fixes work correctly + +### Code Review + +**Getting PR Comments:** +Use `gh-pr-get-comments` script to retrieve all comments on a PR: +```bash +# Get all comments in pretty format +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author (e.g., Copilot bot) +~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' + +# Get unresolved review comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# Get JSON output for parsing +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +**Addressing Review Feedback:** +1. Review all comments from code reviewers and validate their accuracy +2. Discuss false-positives or questionable feedback before making changes +3. Don't just make the minimal change - understand and fix the underlying issue +4. Reply to each comment individually in its thread using `gh-pr-reply-to-thread`: + ```bash + # Reply to a review thread (use thread-id from gh-pr-get-comments output) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' + + # Reply and resolve thread in one command + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + + # Resolve thread without replying (e.g., false positive) + ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only + ``` +5. Include commit links when referencing fixes in replies +6. Resolve threads when issues are fixed, leave unresolved if dismissing/rejecting feedback +7. Re-run linting after addressing comments +8. Push changes promptly to unblock merging +9. After addressing all feedback and pushing, request a new review from Copilot: + ```bash + gh pr edit --add-reviewer @copilot + ``` + +**Important:** Always use the utility scripts (`gh-pr-get-comments` and `gh-pr-reply-to-thread`) instead of raw `gh api` calls for PR comment management. + +### Merging to Default Branch + +- Before merging, ensure the most recent commit was deployed to staging and verified +- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch + - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) + - The `--admin` flag bypasses branch protection rules + - The `-m -d` flags merge and delete the branch after merging +- **Note**: This is only for merging to the default branch, NOT for deploying to staging + +### After Pushing + +1. Update the PR description with latest changes made +2. Verify CI checks are running successfully +3. Check for any new review comments or feedback +4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) + +## Before Committing + +**CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** + +### PHP Changes + +1. Run PHP syntax check: `php -l ` +2. Run phpcs linting: `./vendor/bin/phpcs --standard=phpcs.xml ` +3. Auto-fix with phpcbf if needed: `./vendor/bin/phpcbf --standard=phpcs.xml ` + +### JavaScript/CSS Changes + +1. For JS changes: + ```bash + # Check package.json for project-specific commands + npm run lint:js + # Or if using eslint directly + npx eslint --fix path/to/file.js + ``` + +2. For CSS changes: + ```bash + # Check package.json for project-specific commands + npm run lint:css + # Or if using stylelint directly + npx stylelint --fix path/to/file.css + ``` + +**Note:** Specific commands vary by project. Check `package.json` scripts section for available lint commands. + +### Bash Script Changes + +**MANDATORY: Run ALL these checks before committing ANY Bash script changes:** + +```bash +# 1. Remove trailing whitespace (REQUIRED) +sed -i 's/[[:space:]]*$//' script-name + +# Verify no trailing whitespace in staged changes +git diff --check + +# 2. Format with shfmt (REQUIRED) +shfmt -w script-name + +# Verify formatting is correct +shfmt -d script-name + +# 3. Run ShellCheck with CI-equivalent settings (REQUIRED) +# This must match the severity level used in CI (style severity) +shellcheck --format=gcc --severity=style script-name + +# Or check all modified scripts in your branch +git diff main --name-only --diff-filter=ACMR | \ + xargs shellcheck --format=gcc --severity=style +``` + +**Important ShellCheck Notes:** +- Use `--severity=style` to match CI configuration (not `--severity=warning`) +- Some repositories use differential-shellcheck which checks at "style" level +- SC1091 (sourcing external files) and SC2016 (single quotes) may be acceptable depending on context +- **Zero tolerance policy**: If CI will fail, fix it locally first + +**MANDATORY Pre-Commit Checklist for Bash Scripts:** +- ✅ Trailing whitespace removed (`git diff --check` shows nothing) +- ✅ Script formatted with shfmt (`shfmt -d script-name` shows no diff) +- ✅ ShellCheck passes at style severity (`shellcheck --severity=style`) +- ✅ All variables use `${VAR}` syntax (not `$VAR`) +- ✅ Script tested manually with `--help` flag (if applicable) +- ✅ Documentation updated (README, etc.) + +### General + +1. Verify all tests pass (if applicable) + +## Bash Scripting Standards + +### Variable References + +- **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety +- **Use UPPERCASE for all variables** - Itineris standard: Both script-level and local function variables should be SCREAMING_SNAKE_CASE (note: this differs from typical Bash convention of lowercase for local variables) + +### Formatting Requirements + +- **Remove trailing whitespace** - Run `git diff --check` to verify, `sed -i 's/[[:space:]]*$//' ` to fix +- **Format with shfmt** - Run `shfmt -w ` for consistent indentation (tabs), `shfmt -d ` to verify +- **Lint with shellcheck** - Run `shellcheck --severity=style ` to match CI severity + +## Performance Best Practices + +### Resource Loading + +- Use `preload` for critical CSS/JS with `fetchpriority="high"` +- Add `dns-prefetch` and `preconnect` hints for external resources +- Make resource hints conditional - only add when actually needed +- Avoid render-blocking resources where possible + +**Example:** +```php +// Only preload hero image on pages that use the hero block +add_action('wp_head', function() { + if (has_block('acf/hero-banner')) { + echo ''; + } +}); +``` + +### Conditional Loading + +- Check if blocks/features exist before loading their assets +- Use WordPress's `has_block()` function to detect block usage in content +- Check if scripts are enqueued before adding related resources + +**Example:** +```php +// Only load animations script when hero block is present +add_action('wp_enqueue_scripts', function() { + if (has_block('acf/hero-banner')) { + wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); + } +}); +``` + +## WordPress Specific + +### Hook Priorities + +- Understand hook execution order (wp_enqueue_scripts before wp_head) +- Use appropriate priorities for different types of operations +- Document why specific priorities are chosen + +### Asset Management + +- Use proper asset handles and dependencies +- Defer non-critical JavaScript +- Load CSS appropriately (not everything needs to be async) +- Use manifest files for cache-busting built assets + +## Quick Reference Commands + +### Git Commands + +```bash +# Create feature branch based on ticket source +git checkout -b clickup// # ClickUp +git checkout -b freshdesk// # FreshDesk +git checkout -b issue// # GitHub Issues +git checkout -b feature/ # No ticket + +# Push and track +git push -u origin HEAD + +# Open draft PR +gh pr create --draft --fill + +# Check CI status and merge +gh pr checks --watch && gh pr merge -m -d --admin + +# Or use alias +gh_check_merge --admin + +# Deploy any branch to staging +git push origin :staging --force +``` + +### Linting Commands + +**Bash Scripts:** +```bash +git diff --check # Check trailing whitespace +sed -i 's/[[:space:]]*$//' script.sh # Remove trailing whitespace +shfmt -w script.sh # Format +shfmt -d script.sh # Verify formatting +shellcheck --severity=style script.sh # Lint +``` + +**PHP:** +```bash +php -l file.php # Syntax check +./vendor/bin/phpcs --standard=phpcs.xml file.php # Lint +./vendor/bin/phpcbf --standard=phpcs.xml file.php # Auto-fix +``` + +**JavaScript:** +```bash +npm run lint:js # Project-specific (check package.json) +npx eslint --fix path/to/file.js # Or using eslint directly +``` + +**CSS:** +```bash +npm run lint:css # Project-specific (check package.json) +npx stylelint --fix path/to/file.css # Or using stylelint directly +``` + +### WP CLI Remote Testing + +```bash +# Staging environment +wp @staging option get home +wp @staging cli version +wp @staging cache flush + +# Production environment (⚠️ USE WITH CAUTION) +wp @production option get home # Read-only: safe +wp @production cache flush # Write operation: be careful +``` + +**Warning:** Prefer read-only commands (get, list) on @production. Write operations (set, update, delete) should be rare and deliberate. + +### PR Comment Management + +**Workflow:** Get comments first (to find thread IDs), then reply/resolve using those IDs. + +**Get Comments:** +```bash +# Step 1: Get all comments (includes thread IDs in output) +~/Code/misc/itineris-bin/gh-pr-get-comments + +# Filter by author +~/Code/misc/itineris-bin/gh-pr-get-comments \ + --author='github-advanced-security[bot]' + +# Unresolved comments only +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# JSON output +~/Code/misc/itineris-bin/gh-pr-get-comments --format=json +``` + +**Reply to Comments:** +```bash +# Step 2: Reply using thread-id from step 1 +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_xxx' \ + --message='Fixed in commit abc1234' + +# Reply and resolve +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --message='Fixed in commit abc1234' \ + --resolve + +# Resolve without reply +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_kwDOABCDEF' \ + --resolve-only + +# Request new review after fixes +gh pr edit --add-reviewer @copilot +``` + +### Task/Ticket Management + +```bash +# ClickUp +~/Code/misc/itineris-bin/clickup-get-task + +# FreshDesk +~/Code/misc/itineris-bin/freshdesk-get-ticket +``` + +### GitHub Actions Testing + +```bash +# Install act (one-time) +gh extension install https://github.com/nektos/gh-act + +# Test workflows locally +gh act # Run all workflows +gh act -W .github/workflows/ci.yml # Specific workflow +gh act -j build-test # Specific job +gh act pull_request # Test PR event +gh act -l # List workflows + +# Use larger runner image +gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest +``` + +### Credentials Access + +```bash +# 1Password CLI +op item get "Item Name" --vault "Vault Name" --fields username,password + +# Or on Windows/WSL +op.exe item get "Item Name" --vault "Vault Name" --fields username,password +``` + +### Branch Naming Conventions + +| Ticket Source | Format | Example | +|--------------|--------|---------| +| ClickUp | `clickup//` | `clickup/86bzphaee/landing-page-ammends` | +| FreshDesk | `freshdesk//` | `freshdesk/21170/intro-section-image-position` | +| GitHub Issues | `issue//` | `issue/123/fix-navigation-bug` | +| No ticket | `feature/` or `fix/` | `feature/add-caching`, `fix/header-spacing` | diff --git a/shell/copilot-instructions/README.md b/shell/copilot-instructions/README.md deleted file mode 100644 index de67215..0000000 --- a/shell/copilot-instructions/README.md +++ /dev/null @@ -1,110 +0,0 @@ -# Copilot CLI Instructions for Itineris Development - -## Quick Navigation -- **[Quick Reference](./quick-reference.md)** - Command cheat sheets for instant copy-paste -- **[Git Workflow](./git-workflow.md)** - Branching, PRs, deployment, code review -- **[Code Standards](./code-standards.md)** - PHP, JavaScript, CSS, Bash coding rules -- **[Tools Reference](./tools.md)** - Scripts, utilities, credentials access - ---- - -## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing - -**NEVER push to GitHub without running local lint checks first.** - -### Quick Lint Commands - -**Bash:** -```bash -git diff --check # Check trailing whitespace -shfmt -w script-name && shfmt -d script-name # Format -shellcheck --severity=style script-name # Lint -``` - -**PHP:** -```bash -php -l file.php # Syntax check -./vendor/bin/phpcs --standard=phpcs.xml file.php # Lint -./vendor/bin/phpcbf --standard=phpcs.xml file.php # Auto-fix -``` - -**JavaScript/CSS:** -```bash -npm run lint:js # or: npx eslint --fix file.js -npm run lint:css # or: npx stylelint --fix file.css -``` - -See [Code Standards](./code-standards.md) for detailed language-specific requirements. - -**Zero tolerance policy**: Fix all issues locally. Do not rely on CI to catch problems. - -**When to run lint checks:** -- Ideally: Before committing (catches issues early) -- Mandatory: Before pushing (prevents CI failures) -- Best practice: Set up pre-commit hooks to automate this - ---- - -## Language & Spelling - -- **Always use British English** for all code, comments, documentation, commit messages, and communication -- Common British English spellings to use: - - "optimise" not "optimize" - - "colour" not "color" - - "behaviour" not "behavior" - - "centre" not "center" - - "licence" (noun) / "license" (verb) - - "analyse" not "analyze" -- This applies to variable names, function names, comments, strings, and all written content - ---- - -## Core Workflow Rules - -### Branch Protection -- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) -- **ALWAYS create a feature branch** for any changes -- **ALWAYS create a Pull Request** for review before merging - -### Essential Git Commands -```bash -# Create and push feature branch -git checkout -b clickup// -git push -u origin HEAD - -# Deploy to staging -git push origin HEAD:staging --force - -# Check CI and merge PR -gh pr checks --watch && gh pr merge -m -d --admin -``` - -See [Git Workflow](./git-workflow.md) for complete process. - ---- - -## Communication - -- Ask clarifying questions when requirements are ambiguous -- Provide concise explanations (3 sentences or less typically) -- Focus on doing the work, not explaining what you're about to do -- Let the code and commits speak for themselves - ---- - -## When to Use Which Guide - -**Starting a new task or feature?** -→ Read [Git Workflow](./git-workflow.md) for branch creation and PR process - -**Writing or fixing code?** -→ Check [Code Standards](./code-standards.md) for language-specific rules - -**Need a specific command?** -→ Check [Quick Reference](./quick-reference.md) for copy-paste ready commands - -**Using a script or tool?** -→ Check [Tools Reference](./tools.md) for paths and usage examples - -**Before committing or pushing?** -→ Run lint checks (see Critical section above) + review [Code Standards](./code-standards.md) diff --git a/shell/copilot-instructions/code-standards.md b/shell/copilot-instructions/code-standards.md deleted file mode 100644 index 3420b64..0000000 --- a/shell/copilot-instructions/code-standards.md +++ /dev/null @@ -1,235 +0,0 @@ -# Code Standards - -Language-specific coding standards and linting requirements for Itineris projects. - -## Language & Spelling - -- **Always use British English** for all code, comments, documentation, commit messages, and communication -- Common British English spellings to use: - - "optimise" not "optimize" - - "colour" not "color" - - "behaviour" not "behavior" - - "centre" not "center" - - "licence" (noun) / "license" (verb) - - "analyse" not "analyze" -- This applies to variable names, function names, comments, strings, and all written content - ---- - -## PHP & WordPress Best Practices - -### Variable Handling - -- **NEVER use `global $post`** - Always use `get_post()` instead -- **Always check types properly** - Use `instanceof ClassName` instead of truthy checks -- Import classes with `use` statements at the top of files, not Fully Qualified Names (FQNs) inline - -### Code Quality - -- **Remove all trailing whitespace** - Code must be clean -- **Follow WordPress Coding Standards** strictly -- Use `printf()` or `sprintf()` for HTML construction instead of string concatenation with `echo` -- Escape all output appropriately: - - `esc_url()` for URLs - - `esc_attr()` for HTML attributes - - `esc_html()` for HTML content - - Do not mix `esc_xxx` functions with Blade `{{ }}`. Prefer using WordPress functions with unescaped Blade echo `{!! !!}`. - - INCORRECT: `{{ esc_html($var) }}` - - CORRECT: `{!! esc_html($var) !!}` -- Add phpcs ignore comments with explanations when escaping is already handled -- Do not use `get_posts` or `get_terms`. Use their related query classes `WP_Query` and `WP_Term_Query` - -### Code Style - -- Keep lines under 120 characters -- Add trailing commas to multi-line function calls (PHP 8.0+) -- Use descriptive function and variable names to avoid using comments for explanations. -- Use strict types instead of PHPDoc blocks unless required -- Only use PHPDoc blocks if function or variable names are not clear -- Extract duplicate code into helper functions or methods -- Use `PHP_EOL` for line breaks instead of `"\n"` for consistency - -### Error Handling - -- Always validate JSON decoding with `json_last_error()` and type checks -- Check if resources exist before using them -- Add early returns for guard clauses - -### Compiler-Optimised Functions - -- Always import internal PHP functions with `use function` at the top of the file -- Common functions to import: `strlen`, `count`, `is_array`, `in_array`, `array_key_exists`, etc. -- This enables compiler optimisations for better performance -- Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code -- This is a micro-optimisation but matters when functions are called frequently - ---- - -## JavaScript & CSS Standards - -### JavaScript - -- Run linter with auto-fix before committing -- Check `package.json` for project-specific lint commands -- Common commands: - ```bash - npm run lint:js - npx eslint --fix path/to/file.js - ``` - -### CSS - -- Run linter with auto-fix before committing -- Check `package.json` for project-specific lint commands -- Common commands: - ```bash - npm run lint:css - npx stylelint --fix path/to/file.css - ``` - -**Note:** Specific commands vary by project. Always check `package.json` scripts section for available lint commands. - ---- - -## Bash Scripting Standards - -### Variable References - -- **Always use `${FOO}` syntax** instead of `$FOO` for variable references - provides consistency and safety -- **Use UPPERCASE for all variables** - Itineris standard: Both script-level and local function variables should be SCREAMING_SNAKE_CASE (note: this differs from typical Bash convention of lowercase for local variables) - -### Formatting Requirements - -- **Remove trailing whitespace** - Run `git diff --check` to verify, `sed -i 's/[[:space:]]*$//' ` to fix -- **Format with shfmt** - Run `shfmt -w ` for consistent indentation (tabs), `shfmt -d ` to verify -- **Lint with shellcheck** - Run `shellcheck --severity=style ` to match CI severity - ---- - -## Before Committing - -**CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** - -### PHP Changes - -1. Run PHP syntax check: `php -l ` -2. Run phpcs linting: `./vendor/bin/phpcs --standard=phpcs.xml ` -3. Auto-fix with phpcbf if needed: `./vendor/bin/phpcbf --standard=phpcs.xml ` - -### JavaScript/CSS Changes - -1. For JS changes: - ```bash - # Check package.json for project-specific commands - npm run lint:js - # Or if using eslint directly - npx eslint --fix path/to/file.js - ``` - -2. For CSS changes: - ```bash - # Check package.json for project-specific commands - npm run lint:css - # Or if using stylelint directly - npx stylelint --fix path/to/file.css - ``` - -**Note:** Specific commands vary by project. Check `package.json` scripts section for available lint commands. - -### Bash Script Changes - -**MANDATORY: Run ALL these checks before committing ANY Bash script changes:** - -```bash -# 1. Remove trailing whitespace (REQUIRED) -sed -i 's/[[:space:]]*$//' script-name - -# Verify no trailing whitespace in staged changes -git diff --check - -# 2. Format with shfmt (REQUIRED) -shfmt -w script-name - -# Verify formatting is correct -shfmt -d script-name - -# 3. Run ShellCheck with CI-equivalent settings (REQUIRED) -# This must match the severity level used in CI (style severity) -shellcheck --format=gcc --severity=style script-name - -# Or check all modified scripts in your branch -git diff main --name-only --diff-filter=ACMR | \ - xargs shellcheck --format=gcc --severity=style -``` - -**Important ShellCheck Notes:** -- Use `--severity=style` to match CI configuration (not `--severity=warning`) -- Some repositories use differential-shellcheck which checks at "style" level -- SC1091 (sourcing external files) and SC2016 (single quotes) may be acceptable depending on context -- **Zero tolerance policy**: If CI will fail, fix it locally first - -**MANDATORY Pre-Commit Checklist for Bash Scripts:** -- ✅ Trailing whitespace removed (`git diff --check` shows nothing) -- ✅ Script formatted with shfmt (`shfmt -d script-name` shows no diff) -- ✅ ShellCheck passes at style severity (`shellcheck --severity=style`) -- ✅ All variables use `${VAR}` syntax (not `$VAR`) -- ✅ Script tested manually with `--help` flag (if applicable) -- ✅ Documentation updated (README, etc.) - -### General - -1. Verify all tests pass (if applicable) - ---- - -## Performance Best Practices - -### Resource Loading - -- Use `preload` for critical CSS/JS with `fetchpriority="high"` -- Add `dns-prefetch` and `preconnect` hints for external resources -- Make resource hints conditional - only add when actually needed -- Avoid render-blocking resources where possible - -**Example:** -```php -// Only preload hero image on pages that use the hero block -add_action('wp_head', function() { - if (has_block('acf/hero-banner')) { - echo ''; - } -}); -``` - -### Conditional Loading - -- Check if blocks/features exist before loading their assets -- Use WordPress's `has_block()` function to detect block usage in content -- Check if scripts are enqueued before adding related resources - -**Example:** -```php -// Only load animations script when hero block is present -add_action('wp_enqueue_scripts', function() { - if (has_block('acf/hero-banner')) { - wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); - } -}); -``` - ---- - -## WordPress Specific - -### Hook Priorities - -- Understand hook execution order (wp_enqueue_scripts before wp_head) -- Use appropriate priorities for different types of operations -- Document why specific priorities are chosen - -### Asset Management - -- Use proper asset handles and dependencies -- Defer non-critical JavaScript -- Load CSS appropriately (not everything needs to be async) -- Use manifest files for cache-busting built assets diff --git a/shell/copilot-instructions/git-workflow.md b/shell/copilot-instructions/git-workflow.md deleted file mode 100644 index 51816e5..0000000 --- a/shell/copilot-instructions/git-workflow.md +++ /dev/null @@ -1,182 +0,0 @@ -# Git Workflow - -Complete guide to branching, pull requests, code review, and deployment. - -## Critical Pre-Push Requirements - -**BEFORE PUSHING TO GITHUB:** -1. **ALWAYS run lint checks locally** - See [Code Standards](./code-standards.md) for language-specific commands -2. **ALWAYS verify checks pass** - Zero failures allowed -3. **NEVER push without local validation** - CI failures waste time and create noise - -## Branch Protection - -- **NEVER commit directly to the default branch** (usually `main`, `master`, or `develop`) -- **ALWAYS create a feature branch** for any changes -- **ALWAYS create a Pull Request** for review before merging - ---- - -## Complete Workflow (Order of Operations) - -When implementing a feature or fix: - -1. **Create feature branch** - If on default branch, create and switch to feature branch first -2. **Push branch immediately** - `git push -u origin ` for visibility -3. **Open draft PR early** - Include implementation plan, links to tickets -4. **Make changes & commit after each phase** - Use conventional commit format -5. **Push after each commit** - Enable real-time review on GitHub -6. **Mark PR as "Ready for Review"** - When all phases complete and tests pass -7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed -8. **Deploy to staging for testing** - `git push origin :staging --force` -9. **Verify changes on staging** - Test that the fix/feature works correctly -10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` -11. **Production deployment** - Happens automatically when default branch is pushed - -**Key points:** -- Always verify on staging BEFORE merging to default branch -- Never merge to default branch without staging verification -- Merging to default branch triggers automatic production deployment - ---- - -## Feature Branch Workflow - -When implementing a feature with an implementation plan: - -1. **Check current branch** - If on default branch, create and switch to a feature branch first -2. **Create feature branch** with naming based on ticket source: - - **ClickUp**: `clickup//` (e.g., `clickup/86bzphaee/landing-page-ammends`) - - **FreshDesk**: `freshdesk//` (e.g., `freshdesk/21170/intro-section-image-position`) - - **GitHub Issues**: `issue//` (e.g., `issue/123/fix-navigation-bug`) - - **General** (no ticket): `feature/` or `fix/` (e.g., `feature/add-caching`, `fix/header-spacing`) -3. **Push branch immediately** to GitHub for visibility -4. **Open draft PR early** with: - - Implementation plan in the description - - Clear title describing the feature - - Links to related tickets/documents -5. **Commit after each phase** with conventional commit messages -6. **Push after each commit** for real-time review on GitHub -7. **Update PR description** with progress checkpoints as you go -8. **Mark PR as "Ready for Review"** when all phases complete and tests pass - ---- - -## Commits - -- Write clear, descriptive commit messages -- Use conventional commit format when appropriate (feat:, fix:, docs:, test:, refactor:) -- Explain the "why" not just the "what" in commit messages -- Include context about what problem is being solved -- Commit frequently - after each logical phase or component completion -- Push commits regularly so work can be reviewed incrementally - ---- - -## Pull Requests - -- Create descriptive PR titles and descriptions -- Include "Overview", "Related Tickets & Documents" sections, "Changes", "Impact", "Testing", "Before/After" -- Prompt user for ClickUp, FreshDesk, GitHub, or Sentry links for the "Related Tickets & Documents" section -- Search for related PRs/issues yourself after asking the user -- Open PRs early as drafts to enable real-time review -- Run linting and tests before pushing - ---- - -## Branch Deployment - -- To deploy any branch to an environment: push that branch to the environment branch - - **Staging deployment**: `git push origin :staging --force` - - **Production deployment**: Happens automatically when default branch is pushed -- Works for feature branches, fix branches, or any other branch -- This triggers the CD workflow which deploys to the corresponding environment -- Verify changes on the target environment before proceeding - ---- - -## Testing on Remote Environments - -- **WP CLI aliases** are configured in `wp-cli.yml` for remote testing: - - `@staging` - Staging environment - - `@production` - Production environment - - **⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete) -- Use aliases to test WP CLI commands on remote servers: - - Example: `wp @staging option get home` - - Example: `wp @staging cli version` -- Always test on staging after deployment to verify fixes work correctly - ---- - -## Code Review - -### Getting PR Comments - -Use `gh-pr-get-comments` script to retrieve all comments on a PR: -```bash -# Get all comments in pretty format -~/Code/misc/itineris-bin/gh-pr-get-comments - -# Filter by author (e.g., Copilot bot) -~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' - -# Get unresolved review comments only -~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false - -# Get JSON output for parsing -~/Code/misc/itineris-bin/gh-pr-get-comments --format=json -``` - -### Addressing Review Feedback - -1. Review all comments from code reviewers and validate their accuracy -2. Discuss false-positives or questionable feedback before making changes -3. Don't just make the minimal change - understand and fix the underlying issue -4. Reply to each comment individually in its thread using `gh-pr-reply-to-thread`: - ```bash - # Reply to a review thread (use thread-id from gh-pr-get-comments output) - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' - - # Reply and resolve thread in one command - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' \ - --resolve - - # Resolve thread without replying (e.g., false positive) - ~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --resolve-only - ``` -5. Include commit links when referencing fixes in replies -6. Resolve threads when issues are fixed, leave unresolved if dismissing/rejecting feedback -7. Re-run linting after addressing comments -8. Push changes promptly to unblock merging -9. After addressing all feedback and pushing, request a new review from Copilot: - ```bash - gh pr edit --add-reviewer @copilot - ``` - -**Important:** Always use the utility scripts (`gh-pr-get-comments` and `gh-pr-reply-to-thread`) instead of raw `gh api` calls for PR comment management. - ---- - -## Merging to Default Branch - -- Before merging, ensure the most recent commit was deployed to staging and verified -- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch - - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) - - The `--admin` flag bypasses branch protection rules - - The `-m -d` flags merge and delete the branch after merging -- **Note**: This is only for merging to the default branch, NOT for deploying to staging - ---- - -## After Pushing - -1. Update the PR description with latest changes made -2. Verify CI checks are running successfully -3. Check for any new review comments or feedback -4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) diff --git a/shell/copilot-instructions/quick-reference.md b/shell/copilot-instructions/quick-reference.md deleted file mode 100644 index 6596710..0000000 --- a/shell/copilot-instructions/quick-reference.md +++ /dev/null @@ -1,207 +0,0 @@ -# Quick Reference - -Fast command lookup for common tasks. See main guides for detailed explanations. - -## Git Commands - -### Branch Creation & Push -```bash -# Create feature branch based on ticket source -git checkout -b clickup// # ClickUp -git checkout -b freshdesk// # FreshDesk -git checkout -b issue// # GitHub Issues -git checkout -b feature/ # No ticket - -# Push and track -git push -u origin HEAD -``` - -### Pull Requests -```bash -# Open draft PR -gh pr create --draft --fill - -# Check CI status and merge -gh pr checks --watch && gh pr merge -m -d --admin - -# Or use alias -gh_check_merge --admin -``` - -### Deployment -```bash -# Deploy any branch to staging -git push origin :staging --force - -# Deploy to production (automatic on default branch merge) -# Happens automatically when PR is merged to main/master -``` - ---- - -## Linting Commands - -### Bash Scripts -```bash -# Check trailing whitespace -git diff --check - -# Remove trailing whitespace -sed -i 's/[[:space:]]*$//' script.sh - -# Format with shfmt -shfmt -w script.sh # Apply formatting -shfmt -d script.sh # Verify formatting - -# Lint with shellcheck -shellcheck --severity=style script.sh - -# Check all modified scripts in branch -git diff main --name-only --diff-filter=ACMR | \ - xargs shellcheck --format=gcc --severity=style -``` - -### PHP -```bash -# Syntax check -php -l file.php - -# Lint -./vendor/bin/phpcs --standard=phpcs.xml file.php - -# Auto-fix -./vendor/bin/phpcbf --standard=phpcs.xml file.php -``` - -### JavaScript -```bash -# Project-specific (check package.json) -npm run lint:js - -# Or using eslint directly -npx eslint --fix path/to/file.js -``` - -### CSS -```bash -# Project-specific (check package.json) -npm run lint:css - -# Or using stylelint directly -npx stylelint --fix path/to/file.css -``` - ---- - -## WP CLI Remote Testing - -```bash -# Staging environment -wp @staging option get home -wp @staging cli version -wp @staging cache flush - -# Production environment (⚠️ USE WITH CAUTION) -wp @production option get home # Read-only: safe -wp @production cache flush # Write operation: be careful -``` - -**Warning:** Prefer read-only commands (get, list) on @production. Write operations (set, update, delete) should be rare and deliberate. - ---- - -## PR Comment Management - -**Workflow:** Get comments first (to find thread IDs), then reply/resolve using those IDs. - -### Get Comments -```bash -# Step 1: Get all comments (includes thread IDs in output) -~/Code/misc/itineris-bin/gh-pr-get-comments - -# Filter by author -~/Code/misc/itineris-bin/gh-pr-get-comments \ - --author='github-advanced-security[bot]' - -# Unresolved comments only -~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false - -# JSON output -~/Code/misc/itineris-bin/gh-pr-get-comments --format=json -``` - -### Reply to Comments -```bash -# Step 2: Reply using thread-id from step 1 -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_xxx' \ - --message='Fixed in commit abc1234' - -# Reply and resolve -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' \ - --resolve - -# Resolve without reply -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --resolve-only - -# Request new review after fixes -gh pr edit --add-reviewer @copilot -``` - ---- - -## Task/Ticket Management - -```bash -# ClickUp -~/Code/misc/itineris-bin/clickup-get-task - -# FreshDesk -~/Code/misc/itineris-bin/freshdesk-get-ticket -``` - ---- - -## GitHub Actions Testing - -```bash -# Install act (one-time) -gh extension install https://github.com/nektos/gh-act - -# Test workflows locally -gh act # Run all workflows -gh act -W .github/workflows/ci.yml # Specific workflow -gh act -j build-test # Specific job -gh act pull_request # Test PR event -gh act -l # List workflows - -# Use larger runner image -gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest -``` - ---- - -## Credentials Access - -```bash -# 1Password CLI -op item get "Item Name" --vault "Vault Name" --fields username,password - -# Or on Windows/WSL -op.exe item get "Item Name" --vault "Vault Name" --fields username,password -``` - ---- - -## Branch Naming Conventions - -| Ticket Source | Format | Example | -|--------------|--------|---------| -| ClickUp | `clickup//` | `clickup/86bzphaee/landing-page-ammends` | -| FreshDesk | `freshdesk//` | `freshdesk/21170/intro-section-image-position` | -| GitHub Issues | `issue//` | `issue/123/fix-navigation-bug` | -| No ticket | `feature/` or `fix/` | `feature/add-caching`, `fix/header-spacing` | diff --git a/shell/copilot-instructions/tools.md b/shell/copilot-instructions/tools.md deleted file mode 100644 index cd19055..0000000 --- a/shell/copilot-instructions/tools.md +++ /dev/null @@ -1,176 +0,0 @@ -# Tools Reference - -Scripts, utilities, and tools available for Itineris development workflows. - -## GitHub PR Comment Management - -### Workflow Overview - -1. **First:** Get PR comments to see thread IDs -2. **Then:** Reply/resolve specific threads using the thread IDs from step 1 - -### Step 1: Get PR Comments - -Use `gh-pr-get-comments` to retrieve all comments and their thread IDs: - -```bash -# Get all comments in pretty format (includes thread IDs) -~/Code/misc/itineris-bin/gh-pr-get-comments - -# Filter by author (e.g., Copilot bot) -~/Code/misc/itineris-bin/gh-pr-get-comments --author='github-advanced-security[bot]' - -# Get unresolved review comments only -~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false - -# Get JSON output for parsing -~/Code/misc/itineris-bin/gh-pr-get-comments --format=json -``` - -**Note:** The output includes `thread-id` values (e.g., `PRRT_kwDOABCDEF`) which you need for the next step. - -### Step 2: Reply to PR Comments - -Use `gh-pr-reply-to-thread` with the thread-id from step 1: - -```bash -# Reply to a review thread (use thread-id from gh-pr-get-comments output) -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' - -# Reply and resolve thread in one command -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --message='Fixed in commit abc1234' \ - --resolve - -# Resolve thread without replying (e.g., false positive) -~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ - --thread-id='PRRT_kwDOABCDEF' \ - --resolve-only -``` - -**Important:** Always use these utility scripts instead of raw `gh api` calls for PR comment management. - ---- - -## Task & Ticket Management - -### ClickUp - -Query ClickUp tasks programmatically: - -```bash -~/Code/misc/itineris-bin/clickup-get-task -``` - -### FreshDesk - -Query FreshDesk tickets programmatically: - -```bash -~/Code/misc/itineris-bin/freshdesk-get-ticket -``` - -**Note:** These scripts handle authentication and API interaction automatically. Always use these dedicated scripts instead of making direct API calls. - ---- - -## Credentials Access - -### 1Password CLI - -Use 1Password CLI to retrieve credentials programmatically: - -```bash -# Standard usage -op item get "Item Name" --vault "Vault Name" --fields username,password - -# On Windows/WSL -op.exe item get "Item Name" --vault "Vault Name" --fields username,password -``` - -**Note:** Check project documentation for specific vault and item names for each project. - ---- - -## GitHub Actions Testing - -### Testing Workflows Locally with act - -Before pushing CI workflow changes, test them locally using the [act GitHub CLI extension](https://nektosact.com/installation/gh.html): - -```bash -# Install act as a GitHub CLI extension (one-time) -gh extension install https://github.com/nektos/gh-act - -# Test workflows locally -gh act # Run all workflows -gh act -W .github/workflows/ci.yml # Run specific workflow -gh act -j build-test # Run specific job -gh act pull_request # Test PR event -gh act -l # List available workflows - -# Use larger runner image for better compatibility (includes more tools/packages) -gh act -P ubuntu-latest=catthehacker/ubuntu:full-latest -``` - -**Benefits:** -- Catch errors before pushing to GitHub -- Iterate faster on CI fixes -- No need to spam PR with failed CI runs -- Test different event types locally - -**Limitations:** -- Some features may not work identically (secrets, certain GitHub Actions features) -- Larger runner images can be slow to download first time - ---- - -## WP CLI Remote Testing - -### Configured Aliases - -WP CLI aliases are configured in `wp-cli.yml` for remote testing: -- `@staging` - Staging environment -- `@production` - Production environment - -### Usage - -```bash -# Staging environment (safe for testing) -wp @staging option get home -wp @staging cli version -wp @staging cache flush - -# Production environment (⚠️ USE WITH CAUTION) -wp @production option get home # Read-only: safe -wp @production cache flush # Write operation: be careful -``` - -**⚠️ WARNING**: Use `@production` with caution. Prefer read-only commands (get, list) over write operations (set, update, delete). - -### Testing After Deployment - -Always test on staging after deployment to verify fixes work correctly: - -```bash -# Deploy to staging -git push origin HEAD:staging --force - -# Test the fix -wp @staging option get home -wp @staging cache flush -``` - ---- - -## Quick Command Reference - -See [Quick Reference](./quick-reference.md) for a comprehensive command cheat sheet including: -- Git commands -- Linting commands -- PR management -- Branch naming conventions -- Deployment commands From 134864991f270e795558b77bda1ac0ea4f30f0bc Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:43:16 +0000 Subject: [PATCH 07/14] docs: add comprehensive improvements to copilot instructions Added 8 major enhancements: 1. **Table of Contents** - Quick navigation to all sections with clear hierarchy 2. **Scope & When These Apply** - Clarifies when instructions apply: - Itineris WordPress projects vs personal projects - Project structure and locations - Default branch information 3. **What NOT to Do** - Explicit anti-patterns organized by category: - Git & Deployment violations - Code review mistakes - Code standard violations - Testing & production errors 4. **Common Mistakes to Avoid** - 8 real mistakes Copilot has made: - Committing directly to default branch - Using wrong gh command flags (-md vs -m -d) - Forgetting lints, using gh api instead of scripts - Merging without staging verification - Wrong shellcheck severity, multi-file instructions - Forgetting branch naming conventions 5. **Common Task Patterns** - 4 complete workflow examples: - Fix a bug from FreshDesk ticket (full 10-step workflow) - Address PR code review comments (handle multiple threads) - Implement new feature from ClickUp (multi-phase approach) - Emergency hotfix (fast track for critical issues) 6. **Better Prioritization** - Reorganized structure: - Critical rules and anti-patterns at top - Common workflows before detailed standards - Quick reference easily accessible 7. **Project Information** - Added missing details: - Project locations and structure - How to find default branch - Environment details (staging/production) - CI/CD information - Key tools and support systems - Credentials access patterns 8. **Examples Throughout** - Real-world scenarios with complete command sequences showing full context File grew from 545 to 897 lines but much more useful and actionable. All content is searchable and provides concrete guidance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 352 ++++++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index 20a9e36..530726b 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -1,5 +1,51 @@ # Copilot CLI Instructions for Itineris Development +## 📋 Table of Contents + +**Critical Rules (Read First):** +- [Scope & When These Apply](#scope--when-these-apply) +- [Critical: Lint Checks](#️-critical-always-run-lint-checks-locally-before-pushing) +- [What NOT to Do](#-what-not-to-do) +- [Common Mistakes](#-common-mistakes-to-avoid) + +**Workflows & Patterns:** +- [Quick Reference Commands](#quick-reference-commands) - Copy-paste ready commands +- [Common Task Patterns](#common-task-patterns) - Full workflow examples +- [Git Workflow](#git-workflow) - Branching, PRs, deployment + +**Code Standards:** +- [Language & Spelling](#language--spelling) +- [PHP & WordPress](#php--wordpress-best-practices) +- [JavaScript & CSS](#javascriptcss-changes) +- [Bash Scripting](#bash-scripting-standards) +- [Before Committing](#before-committing) - Pre-commit checklists + +**Reference:** +- [Performance Best Practices](#performance-best-practices) +- [WordPress Specific](#wordpress-specific) +- [Project Information](#project-information) + +--- + +## Scope & When These Apply + +**These instructions apply to:** +- ✅ All Itineris client projects (WordPress sites in `~/Code/wordpress/`) +- ✅ Internal Itineris tools and utilities +- ✅ Projects using Itineris workflows (ClickUp, FreshDesk, custom scripts) + +**These instructions may NOT apply to:** +- ❌ Personal projects outside `~/Code/wordpress/` +- ❌ Open source contributions to non-Itineris projects +- ❌ Non-WordPress projects (ignore PHP/WordPress sections) + +**Project structure:** +- WordPress projects: `~/Code/wordpress//bedrock` +- Utilities and scripts: `~/Code/misc/itineris-bin/` +- Default branch: Usually `main`, `master`, or `develop` (check with `git symbolic-ref refs/remotes/origin/HEAD`) + +--- + ## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing **NEVER push to GitHub without running local lint checks first.** @@ -27,6 +73,276 @@ For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for s --- +## ❌ What NOT to Do + +**NEVER do these things - they violate core workflows:** + +### Git & Deployment +- ❌ **NEVER commit directly to the default branch** - Always create a feature branch first +- ❌ **NEVER merge without staging verification** - Deploy to staging and test before merging +- ❌ **NEVER push without running lints locally** - Zero tolerance for CI failures +- ❌ **NEVER force push to default branch** - Can break production + +### Code Review & PRs +- ❌ **NEVER use `gh api` directly for PR comments** - Always use `~/Code/misc/itineris-bin/gh-pr-get-comments` and `gh-pr-reply-to-thread` +- ❌ **NEVER use combined short flags** - Use `-m -d` not `-md` (gh doesn't support combined short flags) +- ❌ **NEVER skip staging deployment** - Always verify changes on staging before merging + +### Code Standards +- ❌ **NEVER use `global $post`** in PHP - Use `get_post()` instead +- ❌ **NEVER use `get_posts()` or `get_terms()`** - Use `WP_Query` and `WP_Term_Query` instead +- ❌ **NEVER mix escaping with Blade `{{ }}`** - Use `{!! esc_html($var) !!}` not `{{ esc_html($var) }}` +- ❌ **NEVER use American English** - Use British English (colour, optimise, behaviour, etc.) + +### Testing & Production +- ❌ **NEVER test on production first** - Always test on staging +- ❌ **NEVER use `@production` for write operations** without explicit approval - Prefer read-only commands +- ❌ **NEVER skip the CI checks** - Wait for `gh pr checks` to pass before merging + +--- + +## 🚨 Common Mistakes to Avoid + +**These are mistakes Copilot has made in the past - don't repeat them:** + +### 1. Committing Directly to Default Branch +**Mistake:** Making changes and committing without checking current branch +**Fix:** Always check `git branch` and create feature branch if on default branch +```bash +# Check current branch first +git branch --show-current + +# If on default branch (main/master/develop), create feature branch +git checkout -b clickup/task-id/description +``` + +### 2. Using Wrong gh Command Flags +**Mistake:** Using `gh pr merge -md` (combined short flags) +**Fix:** Use separate flags: `gh pr merge -m -d` + +### 3. Forgetting to Run Lints Locally +**Mistake:** Pushing code and letting CI catch linting errors +**Fix:** ALWAYS run lints before pushing (see "Before Committing" section) + +### 4. Using `gh api` Instead of Custom Scripts +**Mistake:** Using `gh api graphql -f query='...'` for PR comments +**Fix:** Use `~/Code/misc/itineris-bin/gh-pr-get-comments ` + +### 5. Merging Without Staging Verification +**Mistake:** Merging PR after CI passes without testing on staging +**Fix:** Always deploy to staging first: `git push origin :staging --force`, then test + +### 6. Using Wrong ShellCheck Severity +**Mistake:** Running `shellcheck script.sh` (defaults to warning level) +**Fix:** Use `shellcheck --severity=style script.sh` to match CI + +### 7. Creating Multi-File Instructions +**Mistake:** Splitting instructions into multiple linked files +**Fix:** Keep everything in ONE file - Copilot CLI doesn't follow relative links + +### 8. Forgetting Branch Naming Convention +**Mistake:** Using generic names like `feature/fix` without ticket reference +**Fix:** Include ticket source: `clickup//description` or `freshdesk//description` + +--- + +## Common Task Patterns + +**Full workflow examples for common scenarios:** + +### Pattern 1: Fix a Bug from FreshDesk Ticket + +**Scenario:** You receive a FreshDesk ticket #21170 reporting broken image positioning on the intro section. + +**Complete workflow:** +```bash +# 1. Check current branch and create feature branch +git branch --show-current +git checkout -b freshdesk/21170/intro-section-image-position + +# 2. Push branch immediately for visibility +git push -u origin HEAD + +# 3. Open draft PR early +gh pr create --draft --fill +# In description: Add ticket link, describe issue, outline fix approach + +# 4. Make the fix, test locally +# ... edit files ... + +# 5. Run lints before committing +./vendor/bin/phpcs --standard=phpcs.xml path/to/changed-file.php +./vendor/bin/phpcbf --standard=phpcs.xml path/to/changed-file.php # auto-fix if needed +npm run lint:css # if CSS was changed + +# 6. Commit with clear message +git add -A +git commit -m "fix: correct intro section image positioning + +Image was overlapping text on mobile due to incorrect z-index +and positioning. Updated CSS to use relative positioning with +proper stacking context. + +Fixes FreshDesk ticket #21170" + +# 7. Push commit +git push + +# 8. Deploy to staging and test +git push origin HEAD:staging --force +# Test on staging environment +wp @staging cache flush +# Visit staging site and verify fix + +# 9. Mark PR as ready for review +gh pr ready + +# 10. Wait for CI and merge +gh pr checks --watch && gh pr merge -m -d --admin +``` + +### Pattern 2: Address PR Code Review Comments + +**Scenario:** You have a PR with 10 unresolved review comments from GitHub Advanced Security bot and human reviewers. + +**Complete workflow:** +```bash +# 1. Get all unresolved comments (note the thread IDs) +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 2. For each comment, fix the issue +# ... make code changes ... + +# 3. Run lints after each fix +./vendor/bin/phpcs --standard=phpcs.xml file.php + +# 4. Commit the fix +git commit -am "fix: address security vulnerability in user input handling + +Added proper sanitization and validation for user-submitted data. +Addresses review comment thread PRRT_xxx." + +# 5. Reply to the specific thread and resolve it +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_xxx' \ + --message='Fixed in commit abc1234' \ + --resolve + +# 6. Repeat steps 2-5 for each comment + +# 7. After all comments addressed, push all commits +git push + +# 8. Request new review +gh pr edit --add-reviewer @copilot + +# 9. Deploy to staging to verify all fixes +git push origin HEAD:staging --force + +# 10. After re-approval, merge +gh pr checks --watch && gh pr merge -m -d --admin +``` + +### Pattern 3: Implement New Feature from ClickUp + +**Scenario:** ClickUp task 86bzphaee asks for landing page amendments - new hero section with CTA. + +**Complete workflow:** +```bash +# 1. Create feature branch +git checkout -b clickup/86bzphaee/landing-page-amendments + +# 2. Push and create draft PR with implementation plan +git push -u origin HEAD +gh pr create --draft --fill +# Add in PR description: +# - Link to ClickUp task +# - Implementation plan with phases +# - Expected timeline +# - Screenshots/mockups if available + +# 3. Implement in phases, committing after each +# Phase 1: Create hero block +# ... create ACF fields, templates ... +git commit -am "feat: add hero section ACF block" +git push + +# Phase 2: Style the hero +# ... add CSS ... +git commit -am "style: add hero section styles with mobile responsive layout" +git push + +# Phase 3: Add CTA functionality +# ... add JS if needed ... +git commit -am "feat: add CTA tracking and form handling" +git push + +# 4. Run all lints before marking ready +./vendor/bin/phpcs --standard=phpcs.xml web/app/themes/*/ +npm run lint:js +npm run lint:css + +# 5. Deploy to staging for client review +git push origin HEAD:staging --force + +# 6. Update PR description with: +# - Before/After screenshots +# - Testing notes +# - Staging URL for review + +# 7. Mark ready and get review +gh pr ready + +# 8. After approval, merge +gh pr checks --watch && gh pr merge -m -d --admin + +# 9. Verify production deployment +# (happens automatically when default branch is pushed) +``` + +### Pattern 4: Emergency Hotfix + +**Scenario:** Production site is down, need immediate fix. + +**Fast workflow:** +```bash +# 1. Create hotfix branch from default +git checkout main # or master/develop +git pull +git checkout -b hotfix/critical-issue-description + +# 2. Make minimal fix only +# ... edit only what's necessary ... + +# 3. Test locally FIRST +# ... verify fix works ... + +# 4. Quick lint check +./vendor/bin/phpcs --standard=phpcs.xml changed-file.php + +# 5. Commit and push +git commit -am "hotfix: resolve critical production issue + +[Describe issue and fix]" +git push -u origin HEAD + +# 6. Create PR and deploy to staging IMMEDIATELY +gh pr create --fill +git push origin HEAD:staging --force + +# 7. Test on staging quickly +wp @staging cache flush +# Verify fix works + +# 8. If verified, merge immediately +gh pr merge -m -d --admin + +# 9. Monitor production +# Watch logs, verify issue is resolved +``` + +--- + ## Language & Spelling - **Always use British English** for all code, comments, documentation, commit messages, and communication @@ -543,3 +859,39 @@ op.exe item get "Item Name" --vault "Vault Name" --fields username,password | FreshDesk | `freshdesk//` | `freshdesk/21170/intro-section-image-position` | | GitHub Issues | `issue//` | `issue/123/fix-navigation-bug` | | No ticket | `feature/` or `fix/` | `feature/add-caching`, `fix/header-spacing` | + +--- + +## Project Information + +**Project locations:** +- WordPress projects: `~/Code/wordpress//bedrock` +- Utility scripts: `~/Code/misc/itineris-bin/` + +**Common default branches:** +- Usually `main`, `master`, or `develop` +- Check with: `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'` + +**Environments:** +- **Staging:** Accessed via `@staging` WP CLI alias, deployed by pushing to `staging` branch +- **Production:** Deployed automatically when default branch is updated + +**CI/CD:** +- GitHub Actions runs on all PRs +- Tests include: PHPUnit, PHPCS, ShellCheck, ESLint, Stylelint (varies by project) +- Must pass before merging + +**Key tools:** +- WP CLI with remote aliases configured in `wp-cli.yml` +- Custom PR management scripts in `~/Code/misc/itineris-bin/` +- 1Password CLI for credentials (`op` command) +- GitHub Actions local testing with `act` (`gh act`) + +**Support:** +- ClickUp for task management: `~/Code/misc/itineris-bin/clickup-get-task ` +- FreshDesk for support tickets: `~/Code/misc/itineris-bin/freshdesk-get-ticket ` +- Sentry for error tracking (check project documentation for URL) + +**Credentials:** +- Stored in 1Password, accessed via CLI: `op item get "Item Name" --vault "Vault Name"` +- Never commit credentials to repos From 369d1def12e2705fd3576885cf789b5383114047 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Thu, 26 Feb 2026 23:52:34 +0000 Subject: [PATCH 08/14] docs: add 6 major operational sections to instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added comprehensive guidance for day-to-day operations and troubleshooting: ## 1. Communication Guidelines (60 lines) - When to ask user vs. proceed autonomously - Always ask: ambiguous requirements, destructive ops, security implications - Proceed: clear requirements, standard patterns, safe operations - How to report progress: concise, outcome-focused, avoid over-explanation - Good vs. bad examples of communication patterns ## 2. Security Best Practices (85 lines) - Input sanitization with WordPress functions - Output escaping (context-appropriate) - SQL injection prevention with $wpdb->prepare() - Nonce verification for CSRF protection - Capability checks (never trust roles) - Credential handling (never log, use 1Password CLI) - File upload security ## 3. Conflict Resolution (70 lines) - Git merge conflict resolution workflow - When to ask user vs. resolve automatically - Package dependency conflicts (composer.lock, package-lock.json) - Database migration conflicts - When/how to abort and ask for help ## 4. Database Operations (95 lines) - CRITICAL safety procedures: backup first, test on staging - Safe migration patterns (adding/removing columns, changing data) - WP CLI database commands (search-replace, query, optimize) - Complete migration workflow (local → staging → production) - Rollback procedures ## 5. Rollback Procedures (130 lines) - Emergency rollback steps (revert deployment immediately) - Rollback database migrations (restore from backup, reverse migration) - Rollback code changes (git revert specific commits) - Rollback dependencies (restore package files) - Prevention strategies - Incident communication (during and after) ## 6. Troubleshooting (220 lines) - CI/CD failures: ShellCheck, PHPCS, test timeouts, build errors - Git issues: SSH keys, detached HEAD, merge conflicts, unrelated histories - WP CLI issues: database connection, timeouts, command not found - Deployment issues: staging not updating, production broken - Linting issues: local vs. CI differences, missing tools - Build issues: missing modules, out of memory - Performance issues: slow site, cache problems - When to ask for help (clear guidelines) ## Impact File evolution: - After Phase 7: 897 lines - After Phase 8: 1552 lines (+655 lines, +73%) Now covers complete operational lifecycle: - ✅ Development workflows - ✅ Security requirements - ✅ Database safety - ✅ Emergency procedures - ✅ Common problems and solutions - ✅ Communication patterns These 6 sections address the most common real-world scenarios and provide clear, actionable guidance for handling them safely. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 659 +++++++++++++++++++++++++++++++++- 1 file changed, 657 insertions(+), 2 deletions(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index 530726b..cc0af09 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -4,6 +4,7 @@ **Critical Rules (Read First):** - [Scope & When These Apply](#scope--when-these-apply) +- [Communication Guidelines](#communication-guidelines) - When to ask vs. proceed - [Critical: Lint Checks](#️-critical-always-run-lint-checks-locally-before-pushing) - [What NOT to Do](#-what-not-to-do) - [Common Mistakes](#-common-mistakes-to-avoid) @@ -11,15 +12,20 @@ **Workflows & Patterns:** - [Quick Reference Commands](#quick-reference-commands) - Copy-paste ready commands - [Common Task Patterns](#common-task-patterns) - Full workflow examples -- [Git Workflow](#git-workflow) - Branching, PRs, deployment +- [Git Workflow](#git-workflow) - Branching, PRs, deployment, conflicts **Code Standards:** - [Language & Spelling](#language--spelling) -- [PHP & WordPress](#php--wordpress-best-practices) +- [PHP & WordPress](#php--wordpress-best-practices) - Security included - [JavaScript & CSS](#javascriptcss-changes) - [Bash Scripting](#bash-scripting-standards) - [Before Committing](#before-committing) - Pre-commit checklists +**Operations & Troubleshooting:** +- [Database Operations](#database-operations) - Migrations, backups, safety +- [Rollback Procedures](#rollback-procedures) - Emergency recovery +- [Troubleshooting](#troubleshooting) - Common issues and solutions + **Reference:** - [Performance Best Practices](#performance-best-practices) - [WordPress Specific](#wordpress-specific) @@ -46,6 +52,68 @@ --- +## Communication Guidelines + +**When to ask the user vs. proceed autonomously:** + +### Always Ask When: +- **Requirements are ambiguous** - Multiple valid interpretations exist +- **Scope is unclear** - Don't know what's in/out of scope +- **Destructive operations** - About to delete/modify critical data +- **Security implications** - Change could affect security posture +- **Breaking changes** - Will break existing functionality +- **Multiple valid approaches** - Need to choose between different architectures +- **User preference matters** - Styling, naming, organizational choices + +### Proceed Autonomously When: +- **Requirements are clear** - User specified exact behavior +- **Standard patterns apply** - Following established conventions +- **Safe operations** - No risk of data loss or breaking changes +- **Single correct approach** - Only one way to solve the problem +- **Fixing obvious bugs** - Clear error, clear fix + +### How to Report Progress: +**DO:** +- Be concise (3 sentences or less typically) +- Focus on outcomes, not process +- Report completion, not intentions +- Let code and commits speak + +**DON'T:** +- Explain every step before doing it +- Ask permission for standard operations +- Over-communicate routine tasks +- Describe what you're about to do in detail + +### Examples: + +**Good:** +``` +User: "Fix the broken image positioning" +You: [Makes fix, commits, pushes] + "Fixed image positioning using relative positioning with z-index adjustment. + Deployed to staging for review." +``` + +**Bad:** +``` +User: "Fix the broken image positioning" +You: "I'm going to investigate the CSS file to identify the positioning issue. + Then I'll create a feature branch and make the necessary changes. + After that I'll run the linters and commit the fix. + Finally I'll push and deploy to staging. + Does this approach sound good to you?" +``` + +**When uncertain:** +``` +User: "Add a contact form" +You: "Should the form send to a specific email address or integrate with + an existing service (e.g., Gravity Forms, Contact Form 7)?" +``` + +--- + ## ⚠️ CRITICAL: Always Run Lint Checks Locally Before Pushing **NEVER push to GitHub without running local lint checks first.** @@ -402,6 +470,68 @@ gh pr merge -m -d --admin - Example: `use function strlen; strlen($str)` instead of `strlen($str)` in namespaced code - This is a micro-optimisation but matters when functions are called frequently +### Security Best Practices + +**Input Sanitization:** +- **ALWAYS sanitize user input** - Never trust any user-supplied data +- Use WordPress sanitization functions: + - `sanitize_text_field()` - for text inputs + - `sanitize_email()` - for email addresses + - `sanitize_url()` - for URLs + - `absint()` - for positive integers + - `sanitize_key()` - for keys/slugs +- Validate before sanitizing - check format, length, allowed values + +**Output Escaping:** +- **ALWAYS escape output** - Already covered in Code Quality section +- `esc_html()`, `esc_attr()`, `esc_url()`, `esc_js()` +- Use context-appropriate escaping + +**SQL Injection Prevention:** +- **NEVER use raw SQL with user input** - Always use prepared statements +- Use `$wpdb->prepare()` for all queries with variables: + ```php + $wpdb->get_results($wpdb->prepare( + "SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_status = %s", + $author_id, + $status + )); + ``` +- Use WP_Query with parameters instead of raw queries when possible + +**Nonce Verification:** +- **ALWAYS verify nonces for forms and AJAX** - Prevent CSRF attacks + ```php + // Generate nonce + wp_nonce_field('my_action', 'my_nonce'); + + // Verify nonce + if (!isset($_POST['my_nonce']) || !wp_verify_nonce($_POST['my_nonce'], 'my_action')) { + wp_die('Security check failed'); + } + ``` + +**Capability Checks:** +- **ALWAYS check user capabilities** - Never trust user roles + ```php + if (!current_user_can('edit_posts')) { + wp_die('Permission denied'); + } + ``` + +**Never Log Credentials:** +- ❌ Never log passwords, API keys, tokens +- ❌ Never commit credentials to repos +- ❌ Never echo sensitive data for debugging +- ✅ Use 1Password CLI for credentials +- ✅ Store secrets in environment variables + +**File Upload Security:** +- Validate file types and sizes +- Use `wp_check_filetype()` for MIME type verification +- Store uploads outside webroot if possible +- Never execute uploaded files + ## Git Workflow ### Critical Pre-Push Requirements @@ -563,6 +693,77 @@ Use `gh-pr-get-comments` script to retrieve all comments on a PR: 3. Check for any new review comments or feedback 4. If all checks pass, move PR from draft to "Ready for Review" (if applicable) +### Conflict Resolution + +**Git Merge Conflicts:** + +When you encounter merge conflicts during pull, merge, or rebase: + +```bash +# 1. Check which files have conflicts +git status + +# 2. Open conflicted files and look for conflict markers: +# <<<<<<< HEAD +# Your changes +# ======= +# Their changes +# >>>>>>> branch-name + +# 3. For each conflict, decide: +# - Keep your changes (remove their changes and markers) +# - Keep their changes (remove your changes and markers) +# - Combine both (merge manually and remove markers) +# - Ask user if unclear which to keep + +# 4. Mark as resolved +git add + +# 5. Continue the operation +git merge --continue # if merging +git rebase --continue # if rebasing +``` + +**When to ask user about conflicts:** +- Business logic conflicts (can't determine correct behavior) +- Both changes look intentional and valid +- Security-sensitive code conflicts +- Database schema conflicts + +**When to resolve automatically:** +- Formatting-only conflicts (whitespace, line endings) +- Obvious merge mistakes (duplicate imports, etc.) +- Auto-generated file conflicts (package-lock.json, composer.lock) + +**Package Dependency Conflicts:** + +```bash +# composer.lock conflicts (PHP) +composer update --lock +git add composer.lock +git commit -m "fix: resolve composer.lock conflict" + +# package-lock.json conflicts (Node) +npm install +git add package-lock.json +git commit -m "fix: resolve package-lock.json conflict" +``` + +**Database Migration Conflicts:** +- If two branches both add migrations with same timestamp → rename one +- If migrations conflict in logic → ask user which to apply first +- Always test migrations on staging after resolving + +**When conflicts are complex:** +```bash +# Abort and ask for help +git merge --abort # or git rebase --abort + +# Ask user: "Merge conflict in critical files: file1.php, file2.php. +# Both changes appear intentional. Should I keep your changes, +# their changes, or would you like to review manually?" +``` + ## Before Committing **CRITICAL: ALWAYS run lint checks locally BEFORE committing or pushing. Do not skip this step.** @@ -685,6 +886,239 @@ add_action('wp_enqueue_scripts', function() { }); ``` +## Database Operations + +**CRITICAL: Database operations can be destructive. Always follow safety procedures.** + +### Before Any Database Changes: + +1. **Backup first** - ALWAYS + ```bash + # Export database + wp @staging db export backup-$(date +%Y%m%d-%H%M%S).sql + + # Or use WP CLI on production (with caution) + wp @production db export backup-$(date +%Y%m%d-%H%M%S).sql + ``` + +2. **Test on staging first** - NEVER run migrations directly on production +3. **Have rollback plan** - Know how to undo the change +4. **Verify backup** - Check file size, test restore on local + +### Safe Migration Patterns: + +**Adding columns (safe):** +```sql +-- Add column with default value +ALTER TABLE wp_tablename ADD COLUMN new_field VARCHAR(255) DEFAULT '' NOT NULL; +``` + +**Removing columns (DANGEROUS - backup first):** +```sql +-- Check column isn't used first +-- Backup database +-- Remove column +ALTER TABLE wp_tablename DROP COLUMN old_field; +``` + +**Changing data (test thoroughly):** +```bash +# Always test on staging first +wp @staging db query "UPDATE wp_options SET option_value = 'new' WHERE option_name = 'specific_option'" + +# Verify change worked +wp @staging option get specific_option + +# Then apply to production only after verification +wp @production db query "UPDATE wp_options SET option_value = 'new' WHERE option_name = 'specific_option'" +``` + +### WP CLI Database Commands: + +```bash +# Search and replace (e.g., domain changes) +wp @staging search-replace 'old-domain.com' 'new-domain.com' --dry-run +wp @staging search-replace 'old-domain.com' 'new-domain.com' --skip-columns=guid + +# Query database +wp @staging db query "SELECT * FROM wp_options WHERE option_name LIKE '%cache%'" + +# Optimize tables +wp @staging db optimize + +# Check database +wp @staging db check + +# Reset database (DANGEROUS - staging only) +wp @staging db reset --yes +``` + +### Migration Workflow: + +1. Write migration in feature branch +2. Test locally with fresh database +3. Commit migration file +4. Deploy to staging +5. Run migration on staging: `wp @staging migrate` +6. Verify staging works correctly +7. Merge to default branch +8. Migration runs automatically on production deploy +9. Monitor production for errors + +### Rollback Database: + +If migration breaks production: +```bash +# 1. Restore from backup (if available) +wp @production db import backup-YYYYMMDD-HHMMSS.sql + +# 2. Or rollback deployment and revert migration +# See Rollback Procedures section +``` + +## Rollback Procedures + +**When deployment breaks production, act fast:** + +### Emergency Rollback Steps: + +**1. Revert the deployment immediately:** +```bash +# Get the last good commit SHA +git log origin/main --oneline -10 + +# Create hotfix branch from last good commit +git checkout +git checkout -b hotfix/rollback-bad-deployment + +# Force push to default branch (EXTREME EMERGENCY ONLY) +git push origin HEAD:main --force + +# Or better: Revert the bad commit +git checkout main +git revert +git push origin main +``` + +**2. Verify production is working:** +```bash +# Check site loads +curl -I https://production-site.com + +# Check for PHP errors +wp @production cli version # If WP CLI responds, PHP is working + +# Clear caches +wp @production cache flush +``` + +**3. Communicate:** +- Notify team immediately in Slack/appropriate channel +- Document what broke and what you did +- Create incident report after resolution + +### Rollback Database Migration: + +**If migration broke database:** + +```bash +# Option 1: Restore from backup (fastest) +wp @production db import backup-YYYYMMDD-HHMMSS.sql +wp @production cache flush + +# Option 2: Write reverse migration +# Create migration that undoes the changes +# Test on staging first, then apply to production + +# Option 3: Manual SQL rollback +wp @production db query "ALTER TABLE wp_tablename DROP COLUMN added_field" +``` + +### Rollback Code Changes: + +**If specific feature broke:** + +```bash +# Revert the specific commit +git revert +git push origin main + +# Or revert multiple commits +git revert .. +git push origin main +``` + +### Rollback Node/PHP Dependencies: + +**If dependency update broke build:** + +```bash +# Restore old package files +git checkout HEAD~1 package.json package-lock.json +npm install +npm run build + +# Or for PHP +git checkout HEAD~1 composer.json composer.lock +composer install +``` + +### Prevention: + +- ✅ Always test on staging before merging +- ✅ Keep backups current (automated daily backups) +- ✅ Use small, incremental changes (easier to rollback) +- ✅ Monitor after deployment (first 15 minutes critical) +- ✅ Have communication plan (know who to notify) + +### Incident Communication: + +**During incident:** +1. Immediate notification: "Production issue - investigating" +2. Status updates every 10-15 minutes +3. Resolution notification: "Fixed - deployed rollback" + +**After incident:** +1. Write incident report +2. Document root cause +3. Create prevention tasks +4. Update runbooks if needed + +## Performance Best Practices + +### Resource Loading + +- Use `preload` for critical CSS/JS with `fetchpriority="high"` +- Add `dns-prefetch` and `preconnect` hints for external resources +- Make resource hints conditional - only add when actually needed +- Avoid render-blocking resources where possible + +**Example:** +```php +// Only preload hero image on pages that use the hero block +add_action('wp_head', function() { + if (has_block('acf/hero-banner')) { + echo ''; + } +}); +``` + +### Conditional Loading + +- Check if blocks/features exist before loading their assets +- Use WordPress's `has_block()` function to detect block usage in content +- Check if scripts are enqueued before adding related resources + +**Example:** +```php +// Only load animations script when hero block is present +add_action('wp_enqueue_scripts', function() { + if (has_block('acf/hero-banner')) { + wp_enqueue_script('hero-animations', get_template_directory_uri() . '/dist/hero.js', [], '1.0', true); + } +}); +``` + ## WordPress Specific ### Hook Priorities @@ -862,6 +1296,227 @@ op.exe item get "Item Name" --vault "Vault Name" --fields username,password --- +## Troubleshooting + +**Common issues and their solutions:** + +### CI/CD Failures + +**"ShellCheck failed":** +```bash +# Problem: Script has shellcheck violations +# Solution: Run shellcheck locally with correct severity +shellcheck --severity=style script.sh + +# Fix issues, then verify +git diff --check # No trailing whitespace +shfmt -d script.sh # Properly formatted +shellcheck --severity=style script.sh # Passes +``` + +**"PHPCS errors":** +```bash +# Problem: PHP code doesn't meet coding standards +# Solution: Auto-fix with phpcbf, then manual fixes +./vendor/bin/phpcbf --standard=phpcs.xml file.php +./vendor/bin/phpcs --standard=phpcs.xml file.php + +# If auto-fix doesn't work, read the errors and fix manually +``` + +**"Tests timeout":** +```bash +# Problem: Tests taking too long or hanging +# Causes: Database connection issues, infinite loops, external API calls +# Solution: Check test logs, add timeouts, mock external services +``` + +**"Build failed - npm/composer errors":** +```bash +# Problem: Dependencies can't install or build fails +# Solution: Clear caches and reinstall + +# Node +rm -rf node_modules package-lock.json +npm install +npm run build + +# PHP +rm -rf vendor composer.lock +composer install +``` + +### Git Issues + +**"Permission denied (publickey)":** +```bash +# Problem: SSH key not configured or not added to agent +# Solution: Check SSH key exists and is added +ls -la ~/.ssh/id_* +ssh-add ~/.ssh/id_rsa # or id_ed25519 +ssh -T git@github.com # Test connection +``` + +**"Detached HEAD state":** +```bash +# Problem: Not on a branch +# Solution: Create branch from current position or checkout existing branch +git checkout -b new-branch-name # Create new branch +# Or +git checkout main # Go back to main branch +``` + +**"Merge conflict" (see Conflict Resolution section above)** + +**"fatal: refusing to merge unrelated histories":** +```bash +# Problem: Trying to merge branches with different roots +# Solution: Use --allow-unrelated-histories (rare, ask user first) +git merge --allow-unrelated-histories +``` + +### WP CLI Connection Issues + +**"Error establishing database connection":** +```bash +# Problem: Can't connect to remote database +# Causes: SSH tunnel issues, credentials wrong, firewall +# Solution: Test SSH connection first +ssh user@staging-server.com + +# Check wp-cli.yml configuration +cat wp-cli.yml + +# Verify SSH key is added +ssh-add -l +``` + +**"Connection timeout":** +```bash +# Problem: WP CLI command hangs +# Solution: Increase timeout or check network +wp @staging option get home --ssh=ssh-user@host:/path --timeout=60 +``` + +**"Command not found: wp":** +```bash +# Problem: WP CLI not installed or not in PATH on remote +# Solution: Check WP CLI is installed on remote server +ssh user@server 'which wp' +``` + +### Deployment Issues + +**"Staging not updating after push":** +```bash +# Problem: Push succeeded but changes not visible +# Causes: Cache, CD workflow didn't run, wrong branch +# Solution: Check GitHub Actions, clear cache + +# Check if deployment ran +gh run list --branch staging --limit 5 + +# Force clear cache +wp @staging cache flush + +# Check correct commit is deployed +ssh user@staging-server 'cd /path/to/site && git log -1' +``` + +**"Production is broken after merge":** +```bash +# Problem: Bug reached production +# Solution: See Rollback Procedures section above +# Immediate: Revert commit and push +git revert +git push origin main +``` + +### Linting Issues + +**"Lint passes locally but fails in CI":** +```bash +# Problem: Different tool versions or configurations +# Solution: Check CI versions match local + +# Check versions +shellcheck --version +./vendor/bin/phpcs --version +node --version + +# Pull latest from repo (may have config changes) +git pull origin main +``` + +**"Can't find command: shellcheck/phpcs/eslint":** +```bash +# Problem: Tools not installed +# Solution: Install tools + +# ShellCheck (varies by OS) +brew install shellcheck # macOS +apt install shellcheck # Linux + +# PHPCS +composer install + +# ESLint +npm install +``` + +### Build Issues + +**"Module not found" errors:** +```bash +# Problem: Missing dependencies +# Solution: Install dependencies +npm install +composer install +``` + +**"Out of memory" during build:** +```bash +# Problem: Node/PHP running out of memory +# Solution: Increase memory limit +export NODE_OPTIONS="--max-old-space-size=4096" +npm run build +``` + +### Performance Issues + +**"Site is slow after deployment":** +```bash +# Problem: Cache not working or query issues +# Solution: Check object cache, database queries + +# Flush all caches +wp @production cache flush + +# Check if object cache is working +wp @production cache type + +# Check slow queries (requires access to database) +``` + +### When to Ask for Help + +**Always ask the user when:** +- Error message is unclear or unfamiliar +- Multiple attempted solutions have failed +- Issue involves production data or security +- Problem requires access you don't have +- Issue is blocking critical work + +**Example:** +``` +"I've encountered a ShellCheck error (SC2086) that I'm not sure how to resolve +without changing the intended behavior. The script uses unquoted variable +expansion intentionally for word splitting. Should I disable this specific +check or refactor the approach?" +``` + +--- + ## Project Information **Project locations:** From abb10230182a1c0a1b9fb8d8266e6d7e702c4494 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Fri, 27 Feb 2026 00:26:34 +0000 Subject: [PATCH 09/14] fix: wait for Copilot review workflow before merging CRITICAL FIX: Copilot review runs as GitHub Actions workflow that takes 1-3 minutes. Previously instructions told Copilot CLI to merge after CI passes, but before review workflow completed, causing critical bugs to be missed. Root cause analysis: - Copilot review is 'Copilot code review' GitHub Actions workflow - Workflow starts ~5s after PR created, takes 1-3 minutes to complete - CI checks (Lint, etc.) complete in <1 minute - Old instructions merged after CI, before review workflow finished Real examples of the problem: - PR #147: Merged at 43s, review workflow completed at 2m24s - PR #149: Merged at 1m51s, review workflow completed at 3m2s - PR #150: Merged at 6m56s, review workflow completed at 7m5s Solution: - Wait for CI: gh pr checks --watch - Wait for review workflow: Loop checking for review from copilot-pull-request-reviewer bot - Only merge after BOTH complete Updated sections: - Merging to Default Branch (lines 721-817) - Pattern 1: FreshDesk workflow (lines 288-301) - Pattern 2: PR comments workflow (lines 335-347) - Pattern 3: ClickUp feature workflow (lines 396-409) - Complete Workflow section (lines 602-604) - Quick Reference Commands (lines 1308-1318) This prevents PRs from being merged before automated review completes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 208 ++++++++++++++++++++++++++++++---- 1 file changed, 185 insertions(+), 23 deletions(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index cc0af09..bb47af0 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -150,11 +150,13 @@ For PHP, JavaScript, CSS: see "Before Committing" section (line 269 below) for s - ❌ **NEVER merge without staging verification** - Deploy to staging and test before merging - ❌ **NEVER push without running lints locally** - Zero tolerance for CI failures - ❌ **NEVER force push to default branch** - Can break production +- ❌ **NEVER merge PR before Copilot review completes** - Wait for `@copilot` review, not just CI checks ### Code Review & PRs - ❌ **NEVER use `gh api` directly for PR comments** - Always use `~/Code/misc/itineris-bin/gh-pr-get-comments` and `gh-pr-reply-to-thread` - ❌ **NEVER use combined short flags** - Use `-m -d` not `-md` (gh doesn't support combined short flags) - ❌ **NEVER skip staging deployment** - Always verify changes on staging before merging +- ❌ **NEVER merge immediately after CI passes** - Wait for human/Copilot reviews to complete ### Code Standards - ❌ **NEVER use `global $post`** in PHP - Use `get_post()` instead @@ -212,6 +214,35 @@ git checkout -b clickup/task-id/description **Mistake:** Using generic names like `feature/fix` without ticket reference **Fix:** Include ticket source: `clickup//description` or `freshdesk//description` +### 9. Merging Before Copilot Review Completes +**Mistake:** Running `gh pr checks --watch && gh pr merge` immediately after CI passes, before Copilot review workflow finishes +**Fix:** Wait for both CI checks AND Copilot review workflow to complete + +```bash +# 1. Wait for CI checks +gh pr checks --watch + +# 2. Wait for Copilot review workflow to complete +PR_NUM=$(gh pr view --json number -q .number) +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + if [ "$STATUS" = "completed" ]; then + echo "✓ Copilot review workflow complete" + break + fi + echo "⏳ Copilot review workflow status: $STATUS (checking again in 30s)" + sleep 30 +done + +# 3. Now safe to merge +gh pr merge -m -d --admin +``` + +**Why this matters:** Copilot review runs as a GitHub Actions workflow that takes 1-3 minutes after CI passes. Merging immediately misses critical review comments and bugs. + +**Real example:** PR #147 merged at 43s, review workflow completed at 2m24s - too late. PR #149 merged at 1m51s, review completed at 3m2s. + --- ## Common Task Patterns @@ -265,8 +296,22 @@ wp @staging cache flush # 9. Mark PR as ready for review gh pr ready -# 10. Wait for CI and merge -gh pr checks --watch && gh pr merge -m -d --admin +# 10. Wait for CI to pass +gh pr checks --watch + +# 11. Wait for Copilot review workflow to complete (DON'T SKIP THIS) +PR_NUM=$(gh pr view --json number -q .number) +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + if [ "$STATUS" = "completed" ]; then + break + fi + sleep 30 +done + +# 12. After BOTH CI and Copilot workflow complete, merge +gh pr merge -m -d --admin ``` ### Pattern 2: Address PR Code Review Comments @@ -298,17 +343,28 @@ Addresses review comment thread PRRT_xxx." # 6. Repeat steps 2-5 for each comment -# 7. After all comments addressed, push all commits -git push - -# 8. Request new review +# 8. After all comments addressed, request new review gh pr edit --add-reviewer @copilot # 9. Deploy to staging to verify all fixes git push origin HEAD:staging --force -# 10. After re-approval, merge -gh pr checks --watch && gh pr merge -m -d --admin +# 10. Wait for CI checks to pass +gh pr checks --watch + +# 11. Wait for Copilot review workflow to complete +PR_NUM=$(gh pr view --json number -q .number) +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + if [ "$STATUS" = "completed" ]; then + break + fi + sleep 30 +done + +# 12. After both CI and Copilot workflow complete, merge +gh pr merge -m -d --admin ``` ### Pattern 3: Implement New Feature from ClickUp @@ -361,8 +417,22 @@ git push origin HEAD:staging --force # 7. Mark ready and get review gh pr ready -# 8. After approval, merge -gh pr checks --watch && gh pr merge -m -d --admin +# 8. Wait for CI to pass +gh pr checks --watch + +# 9. Wait for Copilot review workflow to complete (REQUIRED) +PR_NUM=$(gh pr view --json number -q .number) +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + if [ "$STATUS" = "completed" ]; then + break + fi + sleep 30 +done + +# 10. After both CI and Copilot workflow complete, merge +gh pr merge -m -d --admin # 9. Verify production deployment # (happens automatically when default branch is pushed) @@ -560,8 +630,10 @@ When implementing a feature or fix: 7. **Address code review feedback** - Validate accuracy, reply in threads, resolve when fixed 8. **Deploy to staging for testing** - `git push origin :staging --force` 9. **Verify changes on staging** - Test that the fix/feature works correctly -10. **Merge to default branch** - `gh pr checks --watch && gh pr merge -m -d --admin` -11. **Production deployment** - Happens automatically when default branch is pushed +10. **Wait for CI checks to pass** - `gh pr checks --watch` +11. **Wait for Copilot review workflow to complete** - Check `gh run list --workflow="Copilot code review"` until status is "completed" +12. **Merge to default branch** - `gh pr merge -m -d --admin` (only after both CI and Copilot review complete) +13. **Production deployment** - Happens automatically when default branch is pushed **Key points:** - Always verify on staging BEFORE merging to default branch @@ -679,12 +751,91 @@ Use `gh-pr-get-comments` script to retrieve all comments on a PR: ### Merging to Default Branch -- Before merging, ensure the most recent commit was deployed to staging and verified -- Use `gh pr checks --watch --interval 2 && gh pr merge -m -d --admin` to verify CI and merge PRs to the default branch - - Or use the alias: `gh_check_merge --admin` (the alias handles check-and-merge pattern; add `--admin` flag to bypass branch protection) - - The `--admin` flag bypasses branch protection rules - - The `-m -d` flags merge and delete the branch after merging -- **Note**: This is only for merging to the default branch, NOT for deploying to staging +**🚨 CRITICAL: NEVER merge until BOTH CI passes AND Copilot review workflow completes** + +**The Problem:** Copilot review runs as a GitHub Actions workflow that takes 1-3 minutes. If you merge before it completes, you'll miss critical bugs. + +**How Copilot Review Works:** +- Triggered automatically when PR is created/updated +- Runs as "Copilot code review" GitHub Actions workflow +- Takes 1-3 minutes to analyze code and post review +- Must wait for workflow to complete, not just CI checks + +**Required Workflow:** + +```bash +# 1. Wait for CI checks (Lint, etc.) +gh pr checks --watch + +# 2. Wait for Copilot review workflow to complete (REQUIRED - don't skip!) +PR_NUM=$(gh pr view --json number -q .number) + +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + + if [ "$STATUS" = "completed" ]; then + echo "✓ Copilot review workflow complete" + break + fi + echo "⏳ Copilot review workflow status: $STATUS (checking again in 30s)" + sleep 30 +done + +# 3. Now safe to merge +gh pr merge -m -d --admin +``` + +**How to check manually:** +```bash +# Check Copilot review workflow status +gh run list --workflow="Copilot code review" --limit 5 + +# If status is "completed": OK TO MERGE +# If status is "in_progress" or "queued": WAIT +``` + +**How to check manually:** +```bash +# Check if Copilot review exists (posted by workflow) +gh pr view --json reviews -q '.reviews[] | select(.author.login == "copilot-pull-request-reviewer")' + +# If empty: workflow hasn't completed yet - WAIT +# If shows data: workflow complete - OK TO MERGE + +# Or check workflow run status +gh run list --workflow="Copilot code review" --limit 5 +``` + +**WRONG (what causes the problem):** +```bash +# ❌ BAD: Merges after CI only, doesn't wait for Copilot review workflow +gh pr checks --watch && gh pr merge -m -d --admin +``` + +**Before merging, verify ALL of these:** +1. ✅ Most recent commit was deployed to staging and verified +2. ✅ CI checks (Lint, etc.) have passed +3. ✅ Copilot review workflow has completed (review posted by copilot-pull-request-reviewer) +4. ✅ Any review comments have been addressed + +**Real examples of the problem:** +- PR #147: Merged 43s after creation, review workflow completed at 2m24s +- PR #149: Merged at 00:01:51, review workflow completed at 00:03:02 (1m11s after merge) +- PR #150: Merged at 00:06:56, review workflow completed at 00:07:05 (9s after merge - close!) + +**Timing data:** +- Copilot review workflow starts ~5 seconds after PR created +- Workflow takes 1-3 minutes to complete +- CI checks usually complete in <1 minute +- **Problem:** CI finishes before review workflow + +**⚠️ Do NOT use:** +- `gh_check_merge` alias (only waits for CI, not Copilot workflow) +- `gh pr checks --watch && gh pr merge` (skips Copilot workflow check) +- Any command that merges immediately after CI passes + +**This is only for merging to default branch**, NOT for deploying to staging. ### After Pushing @@ -1151,11 +1302,22 @@ git push -u origin HEAD # Open draft PR gh pr create --draft --fill -# Check CI status and merge -gh pr checks --watch && gh pr merge -m -d --admin - -# Or use alias -gh_check_merge --admin +# Wait for CI and Copilot review workflow, then merge +gh pr checks --watch + +# Wait for Copilot review workflow to complete +PR_NUM=$(gh pr view --json number -q .number) +while true; do + STATUS=$(gh run list --workflow="Copilot code review" --json headBranch,status \ + --jq ".[] | select(.headBranch == \"refs/pull/${PR_NUM}/head\") | .status") + if [ "$STATUS" = "completed" ]; then + break + fi + sleep 30 +done + +# After BOTH complete, merge +gh pr merge -m -d --admin # Deploy any branch to staging git push origin :staging --force From 92e137bd231aa0b20c2ef3fd8179d3b75c3855e7 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Fri, 27 Feb 2026 09:38:07 +0000 Subject: [PATCH 10/14] fix: check for review comments before merging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRITICAL: Agent was merging PRs immediately after Copilot review workflow completed, without checking if there were review comments to address. Problem: - Wait for CI ✓ - Wait for Copilot review workflow ✓ - Check for review comments ✗ (MISSING) - Merge immediately (even with unresolved comments) Solution: Added step to check for unresolved comments before merging: gh-pr-get-comments --resolved=false Updated sections: - Main workflow instructions (lines 785-791) - Common Mistake #9 (lines 238-244) - Pattern 1: FreshDesk workflow (lines 317-322) - Pattern 2: PR comments workflow (lines 370-375) - Pattern 3: ClickUp feature workflow (lines 438-443) - Complete Workflow summary (lines 650-654) - Quick Reference Commands (lines 1342-1348) Now workflow is: 1. Wait for CI 2. Wait for Copilot review workflow 3. Check for review comments 4. Address comments if they exist 5. Only merge after all comments addressed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 52 +++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index bb47af0..6a5ab1f 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -235,7 +235,11 @@ while true; do sleep 30 done -# 3. Now safe to merge +# 3. Check for review comments that need addressing +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 4. If there are unresolved comments, address them first (see Pattern 2) +# If no comments or all addressed, then merge gh pr merge -m -d --admin ``` @@ -310,7 +314,11 @@ while true; do sleep 30 done -# 12. After BOTH CI and Copilot workflow complete, merge +# 12. Check for review comments +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 13. If unresolved comments exist, address them (see Pattern 2) +# If no comments or all addressed, merge gh pr merge -m -d --admin ``` @@ -363,7 +371,11 @@ while true; do sleep 30 done -# 12. After both CI and Copilot workflow complete, merge +# 12. Check for review comments +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 13. If unresolved comments exist, address them first +# If no comments or all addressed, merge gh pr merge -m -d --admin ``` @@ -431,7 +443,11 @@ while true; do sleep 30 done -# 10. After both CI and Copilot workflow complete, merge +# 10. Check for review comments +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 11. If unresolved comments exist, address them first +# If no comments or all addressed, merge gh pr merge -m -d --admin # 9. Verify production deployment @@ -632,8 +648,10 @@ When implementing a feature or fix: 9. **Verify changes on staging** - Test that the fix/feature works correctly 10. **Wait for CI checks to pass** - `gh pr checks --watch` 11. **Wait for Copilot review workflow to complete** - Check `gh run list --workflow="Copilot code review"` until status is "completed" -12. **Merge to default branch** - `gh pr merge -m -d --admin` (only after both CI and Copilot review complete) -13. **Production deployment** - Happens automatically when default branch is pushed +12. **Check for review comments** - Use `gh-pr-get-comments --resolved=false` to see unresolved comments +13. **Address any review comments** - Fix issues, reply to threads, resolve when fixed +14. **Merge to default branch** - `gh pr merge -m -d --admin` (only after all review comments addressed) +15. **Production deployment** - Happens automatically when default branch is pushed **Key points:** - Always verify on staging BEFORE merging to default branch @@ -782,17 +800,25 @@ while true; do sleep 30 done -# 3. Now safe to merge +# 3. Check for review comments that need addressing +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# 4. If there are unresolved comments, address them first (see Pattern 2) +# If no comments or all addressed, then merge gh pr merge -m -d --admin ``` **How to check manually:** ```bash -# Check Copilot review workflow status +# 1. Check Copilot review workflow status gh run list --workflow="Copilot code review" --limit 5 - -# If status is "completed": OK TO MERGE # If status is "in_progress" or "queued": WAIT +# If status is "completed": Continue to step 2 + +# 2. Check for review comments +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false +# If comments exist: Address them first +# If no comments: OK TO MERGE ``` **How to check manually:** @@ -1316,7 +1342,11 @@ while true; do sleep 30 done -# After BOTH complete, merge +# Check for review comments +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# If comments exist, address them first +# If no comments or all addressed, merge gh pr merge -m -d --admin # Deploy any branch to staging From 9b1b168cb285755e009290f655577c9cd34b5964 Mon Sep 17 00:00:00 2001 From: codepuncher Date: Fri, 27 Feb 2026 10:20:03 +0000 Subject: [PATCH 11/14] docs: add guidance for FreshDesk/ClickUp ticket handling Problem: Agent tried to use web_fetch for FreshDesk tickets instead of using the dedicated freshdesk-get-ticket script with authentication. Added comprehensive section "Working with Tickets and Tasks": - Clear guidance to use scripts for FreshDesk/ClickUp URLs - Explanation of why scripts are better (auth, structured data, private access) - Examples showing URL pattern recognition - Workflow for extracting IDs and creating branches Added Common Mistake #5: - Using web_fetch for FreshDesk/ClickUp - Shows correct script usage with examples Updates: - New section after "Scope & When These Apply" (lines 54-103) - Common Mistake #5 added (lines 252-263) - Renumbered mistakes 5-9 to 6-10 This ensures agents recognize ticket URLs and use proper authenticated scripts instead of attempting web scraping. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 65 ++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index 6a5ab1f..3451356 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -52,6 +52,57 @@ --- +## Working with Tickets and Tasks + +**When given a ticket/task URL or ID, use the appropriate script:** + +### FreshDesk Tickets +**URLs:** `https://itineris.freshdesk.com/a/tickets/` or `https://itineris.freshdesk.com/helpdesk/tickets/` + +```bash +# Use the freshdesk-get-ticket script (NOT web_fetch) +~/Code/misc/itineris-bin/freshdesk-get-ticket + +# Example +~/Code/misc/itineris-bin/freshdesk-get-ticket 21062 +``` + +**Why use the script:** +- Authenticated access with API credentials +- Returns structured data (title, description, requester, status) +- Works with private tickets that web_fetch cannot access +- Faster and more reliable than web scraping + +### ClickUp Tasks +**URLs:** `https://app.clickup.com/t/` + +```bash +# Use the clickup-get-task script +~/Code/misc/itineris-bin/clickup-get-task + +# Example +~/Code/misc/itineris-bin/clickup-get-task 86bzphaee +``` + +### When User Provides URL +1. **Extract the ticket/task ID from the URL** +2. **Use the appropriate script** (don't use web_fetch for FreshDesk/ClickUp) +3. **Create feature branch** with correct naming: `freshdesk//` or `clickup//` + +**Example:** +``` +User: "Do this task: https://itineris.freshdesk.com/a/tickets/21062" + +# Extract ID: 21062 +# Use script: +~/Code/misc/itineris-bin/freshdesk-get-ticket 21062 + +# Create branch: +git checkout -b freshdesk/21062/description-from-ticket +``` + +--- + ## Communication Guidelines **When to ask the user vs. proceed autonomously:** @@ -198,7 +249,19 @@ git checkout -b clickup/task-id/description **Mistake:** Using `gh api graphql -f query='...'` for PR comments **Fix:** Use `~/Code/misc/itineris-bin/gh-pr-get-comments ` -### 5. Merging Without Staging Verification +### 5. Using web_fetch for FreshDesk/ClickUp +**Mistake:** Using `web_fetch` to access FreshDesk or ClickUp URLs +**Fix:** Use dedicated scripts with authentication: +```bash +# FreshDesk tickets +~/Code/misc/itineris-bin/freshdesk-get-ticket + +# ClickUp tasks +~/Code/misc/itineris-bin/clickup-get-task +``` +**Why:** These scripts have proper API authentication, return structured data, and work with private tickets that web_fetch cannot access. + +### 6. Merging Without Staging Verification **Mistake:** Merging PR after CI passes without testing on staging **Fix:** Always deploy to staging first: `git push origin :staging --force`, then test From b905f0bb688f5e9fbddc3791f96924192144df9f Mon Sep 17 00:00:00 2001 From: codepuncher Date: Fri, 27 Feb 2026 11:18:28 +0000 Subject: [PATCH 12/14] docs: add comprehensive quality and operational guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added 10 major improvements covering quality, performance, and operations: HIGH PRIORITY (Common Pain Points): 1. **Handling Copilot Review Comments** (60 lines) - Prioritize by severity (security > bugs > quality > style) - Validate accuracy before changing (false positives) - When to address automatically vs ask user - Handling multiple comments and conflicts with requirements 2. **Failed CI After Push** (50 lines) - What to do when CI fails (was missing) - How to fix linting, tests, and build failures locally - When to ask user for help 3. **Post-Merge Production Verification** (65 lines) - Wait for deployment, verify artifacts - Basic smoke tests and monitoring - What to check and when - How to handle issues detected 4. **Squashing Commit History** (60 lines) - When to squash vs preserve commits - Three methods: squash merge, interactive rebase, reset - Default approach guidance MEDIUM PRIORITY (Quality Improvements): 5. **Dependency Update Strategy** (55 lines) - Safe update process - Check changelogs, test thoroughly - Document major updates - When to update vs when not to 6. **Performance Checks** (75 lines) - Database query optimization - Asset size checks - PageSpeed/Lighthouse testing - Query Monitor usage 7. **Accessibility Basics** (85 lines) - Keyboard navigation, screen readers - Semantic HTML, alt text, color contrast - Form labels, WCAG compliance - When to do thorough testing 8. **SEO Considerations** (95 lines) - Meta tags, heading hierarchy - URL structure, structured data - Image optimization, internal linking - Quick SEO checks LOWER PRIORITY (Specific Scenarios): 9. **Incident Communication** (75 lines) - Assess severity (P0/P1/P2) - Who to notify and when - Progress updates during incidents - Post-mortem documentation 10. **Multisite WordPress** (55 lines) - Network-wide vs site-specific changes - Testing on multisite - Deployment considerations TOTAL ADDITIONS: - +675 lines of guidance - File: 1,807 → 2,478 lines (+37% growth) These additions address common quality issues, improve operational procedures, and provide clear guidance for complex scenarios. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/copilot-instructions.md | 679 +++++++++++++++++++++++++++++++++- 1 file changed, 675 insertions(+), 4 deletions(-) diff --git a/shell/copilot-instructions.md b/shell/copilot-instructions.md index 3451356..5ece501 100644 --- a/shell/copilot-instructions.md +++ b/shell/copilot-instructions.md @@ -265,19 +265,19 @@ git checkout -b clickup/task-id/description **Mistake:** Merging PR after CI passes without testing on staging **Fix:** Always deploy to staging first: `git push origin :staging --force`, then test -### 6. Using Wrong ShellCheck Severity +### 7. Using Wrong ShellCheck Severity **Mistake:** Running `shellcheck script.sh` (defaults to warning level) **Fix:** Use `shellcheck --severity=style script.sh` to match CI -### 7. Creating Multi-File Instructions +### 8. Creating Multi-File Instructions **Mistake:** Splitting instructions into multiple linked files **Fix:** Keep everything in ONE file - Copilot CLI doesn't follow relative links -### 8. Forgetting Branch Naming Convention +### 9. Forgetting Branch Naming Convention **Mistake:** Using generic names like `feature/fix` without ticket reference **Fix:** Include ticket source: `clickup//description` or `freshdesk//description` -### 9. Merging Before Copilot Review Completes +### 10. Merging Before Copilot Review Completes **Mistake:** Running `gh pr checks --watch && gh pr merge` immediately after CI passes, before Copilot review workflow finishes **Fix:** Wait for both CI checks AND Copilot review workflow to complete @@ -442,6 +442,97 @@ done gh pr merge -m -d --admin ``` +### How to Handle Copilot Review Comments + +**When Copilot review posts comments, evaluate each one carefully:** + +#### 1. Prioritize Comments by Severity +- **Security vulnerabilities** (SQL injection, XSS, etc.) - Fix immediately +- **Bugs/Logic errors** - Fix immediately +- **Performance issues** - Fix if significant impact +- **Code quality** (complexity, duplication) - Fix if reasonable +- **Style/formatting** - Fix if violates project standards +- **Nitpicks** - Use judgment, may skip if trivial + +#### 2. Validate Comment Accuracy +Not all Copilot comments are correct. Validate before changing: + +```bash +# Get the comment +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false + +# Research the issue +# - Check if vulnerability exists in your context +# - Review if logic error is actually wrong +# - Test the suggested fix +``` + +**When comment is a false positive:** +```bash +# Reply explaining why it doesn't apply +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_xxx' \ + --message="This is a false positive because [explanation]. The code is correct as-is." \ + --resolve +``` + +#### 3. When to Address Automatically vs Ask User + +**Address automatically:** +- Security vulnerabilities with clear fixes +- Obvious bugs (typos, wrong variable names) +- Missing input validation/escaping +- Clear performance improvements +- Lint/formatting issues + +**Ask user first:** +- Architectural changes +- Business logic modifications +- Breaking changes to APIs +- Comments suggesting different approach +- When fix has trade-offs + +#### 4. Addressing Multiple Comments + +**Workflow for multiple comments:** +```bash +# 1. Categorize comments by severity +~/Code/misc/itineris-bin/gh-pr-get-comments --resolved=false > review.txt + +# 2. Fix all security issues first (separate commit) +git commit -m "security: fix SQL injection vulnerability" + +# 3. Fix bugs (separate commit) +git commit -m "fix: correct calculation in total_price" + +# 4. Fix quality issues (can combine) +git commit -m "refactor: reduce complexity and improve readability" + +# 5. Push all fixes +git push + +# 6. Reply to each thread individually +~/Code/misc/itineris-bin/gh-pr-reply-to-thread --thread-id='...' --message='...' --resolve +``` + +#### 5. When Comments Conflict with Requirements + +If Copilot suggests changes that conflict with user requirements: +1. **Prioritize user requirements** - They know the business context +2. **Reply to comment** - Explain why requirement takes precedence +3. **Suggest compromise** - If there's a way to address both + +**Example:** +```bash +~/Code/misc/itineris-bin/gh-pr-reply-to-thread \ + --thread-id='PRRT_xxx' \ + --message="User specifically requested this approach due to [business reason]. + I've added validation to mitigate the concern you raised." \ + --resolve +``` + +--- + ### Pattern 3: Implement New Feature from ClickUp **Scenario:** ClickUp task 86bzphaee asks for landing page amendments - new hero section with CTA. @@ -558,6 +649,149 @@ gh pr merge -m -d --admin # Watch logs, verify issue is resolved ``` +### Incident Communication for Hotfixes + +**When deploying emergency hotfixes:** + +#### 1. Before Starting +**Assess severity:** +- Is site completely down? (P0 - Critical) +- Is key functionality broken? (P1 - High) +- Is minor feature broken? (P2 - Medium) + +**For P0/P1 incidents, notify stakeholders:** +``` +User: "Site is down - critical issue" + +Agent: I'm deploying an emergency hotfix for [issue]. + I'll notify you when: + 1. Fix is deployed to staging + 2. Fix is deployed to production + 3. Verification is complete +``` + +#### 2. During Incident +**Keep user informed of progress:** +- "Identified root cause: [brief explanation]" +- "Hotfix deployed to staging, testing now" +- "Staging verified, deploying to production" + +**Don't wait for permission on P0 incidents:** +- Fix first, discuss later +- Document decisions in PR +- Notify as you work, don't block on approval + +#### 3. After Resolution +**Provide incident summary:** +``` +Incident resolved ✓ + +Root cause: [What caused the issue] +Fix applied: [What was changed] +Deployed: [Timestamp] +Verification: [What was tested] + +Monitoring for 10 minutes to ensure stability. +``` + +#### 4. Post-Mortem (for major incidents) +**Document for learning:** +- What happened? +- What was the impact? +- What was the root cause? +- What was the fix? +- How can we prevent this? + +**Ask user:** +"Should I create a post-mortem document for this incident?" + +#### 5. Who to Notify +**Ask user at start of incident:** +- "Should I notify anyone else about this incident?" +- "Are there any communication channels I should post to?" + +**Typical stakeholders:** +- Project manager +- Client (for client sites) +- Team lead +- On-call engineer + +**Remember:** +- For P0 (site down): Communicate every 5-10 minutes +- For P1 (major feature down): Communicate at key milestones +- For P2 (minor issue): Standard workflow is fine + +### Post-Merge Production Verification + +**After merging to default branch, deployment happens automatically. Verify it succeeded:** + +#### 1. Wait for Deployment to Complete +```bash +# Check recent workflow runs +gh run list --limit 5 + +# If deploy workflow exists, wait for it +gh run watch +``` + +#### 2. Verify Deployment Artifacts +```bash +# Check latest commit is deployed +git log origin/main -1 --oneline +# Note the commit SHA + +# If deployment creates tags/releases +gh release list --limit 5 +``` + +#### 3. Basic Smoke Tests +```bash +# Test production site is responding +curl -I https://production-site.com + +# Check for PHP errors (if wp-cli available) +wp @production cli version + +# Check error logs for new errors +# (Project-specific - check documentation for log location) +``` + +#### 4. Monitor for Errors +**For first 5-10 minutes after deployment:** +- Check Sentry for new errors (if configured) +- Monitor server logs +- Check site performance/responsiveness +- Test the specific feature you deployed + +#### 5. If Issues Detected +```bash +# Option 1: Quick fix +git checkout -b hotfix/production-issue +# Make minimal fix +git commit -am "hotfix: fix production issue" +git push -u origin HEAD +gh pr create --fill +# Fast-track review and merge + +# Option 2: Rollback (see Rollback Procedures section) +git revert HEAD +git push origin main +``` + +**When to verify:** +- Always for hotfixes +- Always for breaking changes +- Always for database migrations +- For major features (user-facing changes) +- When deployment changes infrastructure + +**When verification can be lighter:** +- Minor copy changes +- Internal tooling updates +- Documentation changes + +--- + --- ## Language & Spelling @@ -750,6 +984,60 @@ When implementing a feature with an implementation plan: - Commit frequently - after each logical phase or component completion - Push commits regularly so work can be reviewed incrementally +### Squashing and Cleaning Commit History + +**During development:** Commit frequently for incremental review + +**Before merging:** Consider cleaning up commit history + +#### When to Squash: +- Multiple "fix typo" or "address review comments" commits +- WIP commits that don't add value to history +- Commits that should logically be one change +- When PR has >10 commits for a small feature + +#### How to Squash: + +**Option 1: Use squash merge (simplest)** +```bash +# When merging PR, use squash flag +gh pr merge --squash -d +``` + +**Option 2: Manual squash before merge** +```bash +# Squash last N commits +git rebase -i HEAD~N + +# In editor, change "pick" to "squash" for commits to combine +# Edit commit message to summarize all changes + +# Force push (safe because it's your feature branch) +git push --force-with-lease +``` + +**Option 3: Reset and re-commit** +```bash +# Soft reset to default branch +git reset --soft $(git merge-base HEAD origin/main) + +# All changes now staged, create single commit +git commit -m "feat: implement feature XYZ + +Detailed description of all changes" + +# Force push +git push --force-with-lease +``` + +**When NOT to squash:** +- Each commit represents a distinct, logical change +- Commits are already clean and well-organized +- Large PRs where history helps understand progression +- When commit separation aids in future debugging + +**Default approach:** Use squash merge (`gh pr merge --squash`) unless there's a reason to preserve individual commits. + ### Pull Requests - Create descriptive PR titles and descriptions @@ -1077,6 +1365,279 @@ git diff main --name-only --diff-filter=ACMR | \ ### General 1. Verify all tests pass (if applicable) +2. Check for performance impact (see Performance Checks below) +3. Check accessibility if UI changes (see Accessibility below) +4. Check SEO impact if content/meta changes (see SEO below) + +### Dependency Updates + +**When updating composer or npm dependencies:** + +#### 1. Check for Breaking Changes +```bash +# For composer +composer update --dry-run +composer show # Check version changes + +# For npm +npm outdated +npm view versions +``` + +#### 2. Review Changelogs +- Always review CHANGELOG or release notes +- Look for breaking changes, deprecated features +- Check minimum PHP/Node version requirements + +#### 3. Update Dependencies Safely +```bash +# For composer (update one package at a time) +composer update --with-all-dependencies +composer update # Or all packages + +# For npm +npm update +npm update # Or all packages + +# Commit the lock file +git add composer.lock package-lock.json +git commit -m "chore: update dependencies" +``` + +#### 4. Test Thoroughly After Updates +- Run all tests: `./vendor/bin/phpunit`, `npm test` +- Test locally: Visit all major pages/features +- Deploy to staging: Test full user workflows +- Check for deprecation warnings in logs + +#### 5. Document Major Updates +```bash +# For major version bumps, document in commit message +git commit -m "chore: update package X from v1 to v2 + +BREAKING CHANGES: +- Method Y renamed to Z +- Config format changed + +Tested: +- All unit tests pass +- Manual testing on staging +- No errors in logs" +``` + +**When to update:** +- Security vulnerabilities (immediately) +- Bug fixes affecting you (soon) +- New features you need (when ready) +- Major versions (carefully, with testing) + +**When NOT to update:** +- Right before a deadline +- Without testing on staging first +- Multiple major versions at once + +### Performance Checks + +**Check performance impact for:** +- Database queries (especially in loops) +- Image/asset loading +- JavaScript bundle size +- CSS file size + +#### Quick Performance Checks: + +**1. Database Queries:** +```bash +# Enable Query Monitor plugin on staging +wp @staging plugin activate query-monitor + +# Or check queries in code +# Add to wp-config.php temporarily: +# define('SAVEQUERIES', true); + +# Look for: +# - N+1 queries +# - Slow queries (>0.05s) +# - Duplicate queries +``` + +**2. Asset Sizes:** +```bash +# Check bundle sizes +npm run build +ls -lh dist/ # Or build output directory + +# Warn if: +# - JS bundle >500KB +# - CSS bundle >100KB +# - Individual images >500KB (unless hero images) +``` + +**3. PageSpeed/Lighthouse:** +```bash +# For major UI changes, test with Lighthouse +# Run in Chrome DevTools or: +npx lighthouse https://staging-site.com --view + +# Target scores: +# - Performance: >80 +# - Accessibility: >90 +``` + +**4. Database Query Optimization:** +```php +// Use proper indexes +// Cache expensive queries +// Avoid queries in loops + +// WRONG: +foreach ($posts as $post) { + $meta = get_post_meta($post->ID, 'key', true); // Query in loop! +} + +// RIGHT: +$post_ids = wp_list_pluck($posts, 'ID'); +$all_meta = get_post_meta($post_ids, 'key'); // Single query +``` + +### Accessibility Checks + +**For UI changes, check basic accessibility:** + +#### 1. Keyboard Navigation +- Can you tab through all interactive elements? +- Is focus visible? +- Can you activate buttons/links with Enter/Space? + +#### 2. Screen Reader Testing +```bash +# Test with VoiceOver (macOS): +# Cmd+F5 to toggle, Ctrl+Option+arrows to navigate + +# Or test with NVDA (Windows - free) +``` + +#### 3. Semantic HTML +```php +// Use proper HTML5 elements +