{"id":31040096,"url":"https://github.com/e0ipso/gh_contrib_template","last_synced_at":"2026-05-08T09:32:16.177Z","repository":{"id":314565258,"uuid":"1055999123","full_name":"e0ipso/gh_contrib_template","owner":"e0ipso","description":"A GitHub repository template for creating Drupal contrib modules with comprehensive testing infrastructure, code quality tools, and AI-friendly development environment.","archived":false,"fork":false,"pushed_at":"2025-12-17T15:31:20.000Z","size":107,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-21T03:49:55.697Z","etag":null,"topics":["contrib","drupal","github"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/e0ipso.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-09-13T07:25:59.000Z","updated_at":"2025-12-17T15:31:24.000Z","dependencies_parsed_at":"2025-09-13T09:45:02.361Z","dependency_job_id":"b5b88784-63b8-48e6-baa8-70cb4dc4ec96","html_url":"https://github.com/e0ipso/gh_contrib_template","commit_stats":null,"previous_names":["e0ipso/gh_contrib_template"],"tags_count":12,"template":true,"template_full_name":null,"purl":"pkg:github/e0ipso/gh_contrib_template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e0ipso%2Fgh_contrib_template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e0ipso%2Fgh_contrib_template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e0ipso%2Fgh_contrib_template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e0ipso%2Fgh_contrib_template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/e0ipso","download_url":"https://codeload.github.com/e0ipso/gh_contrib_template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e0ipso%2Fgh_contrib_template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32774756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contrib","drupal","github"],"created_at":"2025-09-14T08:07:27.506Z","updated_at":"2026-05-08T09:32:16.166Z","avatar_url":"https://github.com/e0ipso.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 GitHub Contrib Template\n\nA GitHub repository template for creating Drupal contrib modules with comprehensive testing infrastructure, code quality tools, and AI-friendly development environment. Because writing boilerplate is so last century! ✨\n\n## 🎯 Quick Start\n\n1. 🖱️ Click \"Use this template\" on GitHub to create a new repository\n2. 📥 Clone your new repository locally\n3. 🛠️ Follow the setup instructions below to customize for your module\n\n## Setup Instructions\n\nAfter creating a repository from this template, follow these steps:\n\n### 1. Rename Files and References\n\nReplace all instances of `gh_contrib_template` with your actual module name:\n\n- Rename `gh_contrib_template.info.yml` to `your_module_name.info.yml`\n- Update module name references in all files\n- Update namespace references in PHP files\n- Update test class names and namespaces\n\n### 2. Install Git Hooks\n\nAfter cloning, install the pre-commit hooks that will automatically check code quality:\n\n```bash\nnpm install  # Installs husky and other dependencies\n```\n\nThis sets up automatic git hooks for:\n\n- **Pre-commit**: Code quality checks\n  - PHP coding standards (Drupal/DrupalPractice)\n  - PHPStan static analysis\n  - JavaScript/CSS linting\n  - Code formatting\n- **Commit-msg**: Enforces [Conventional Commits](https://www.conventionalcommits.org/) format\n  - Example: `feat: add user authentication`\n  - Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert\n- **Pre-push**: Validates branch naming ([Lullabot ADR](https://architecture.lullabot.com/adr/20220920-git-branch-naming/))\n  - Format: `[ticket-id]--[description]`\n  - Examples: `DRUPAL-123--fix-menu-bug`, `NOTICKET--update-readme`\n\n### 3. Configure AI Assistant (Optional)\n\nIf you plan to use AI assistants for development:\n\n- Rename `AGENTS.md` to match your preferred assistant (e.g., `CLAUDE.md`, `GEMINI.md`)\n- Rename `tests/e2e/AGENTS.md` to match your preferred assistant (e.g., `CLAUDE.md`, `GEMINI.md`)\n- Install the AI task manager:\n\n```bash\nnpx @e0ipso/ai-task-manager init --assistants claude,gemini,opencode\n```\n\n### 4. Configure GitHub Actions Permissions\n\n\u003cdetails\u003e\n\u003csummary\u003e⚠️ \u003cstrong\u003eFix \"Permission denied\" errors in GitHub Actions\u003c/strong\u003e\u003c/summary\u003e\n\n#### Quick Fix\n\nGo to your repository **Settings** → **Actions** → **General** → **Workflow permissions**:\n\n- Select **Read and write permissions**\n- Check **Allow GitHub Actions to create and approve pull requests**\n- Click **Save**\n\n#### Alternative: Personal Access Token\n\n1. Create a [Personal Access Token](https://github.com/settings/tokens/new?scopes=repo,workflow) with `repo` and `workflow` scopes\n2. Add it to your repository: **Settings** → **Secrets** → **Actions** → **New repository secret**\n   - Name: `GH_TOKEN`\n   - Value: Your token\n3. Update `.github/workflows/release.yml`:\n   ```yaml\n   env:\n     GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}\n   ```\n\n#### Best Practice: Service Accounts\n\nFor team projects, use a dedicated bot account ([Lullabot ADR reference](https://architecture.lullabot.com/adr/20220426-use-dedicated-accounts-service-integrations/)):\n\n- Create a bot GitHub account (e.g., `your-project-bot`)\n- Add it as a collaborator with write permissions\n- Use its PAT for automated workflows\n- Benefits: Not tied to personal accounts, easier rotation, clear audit trail\n\n\u003c/details\u003e\n\n### 5. Update Module Information\n\n- Edit the `.info.yml` file with your module's details\n- Update `composer.json` with your module's metadata\n- Customize the module description and dependencies\n\n\u003e **Note**: This template is designed for modules hosted on GitHub with `vendor/module-name` namespacing (e.g., `lullabot/my-module`). For Drupal.org contrib modules requiring `drupal/module-name` namespacing, you can use GitHub Actions to mirror your repository to GitLab whenever new tags are created.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📦 Publish to Packagist for Composer Installation\u003c/strong\u003e\u003c/summary\u003e\n\nTo enable `composer require vendor/module-name` installation:\n\n1. **Ensure your `composer.json` is properly configured** with:\n\n- Correct `name` field (e.g., `\"lullabot/my-module\"`)\n- `type: \"drupal-module\"`\n- Proper `description` and `keywords`\n\n2. **Submit to Packagist**:\n\n- Visit [packagist.org](https://packagist.org)\n- Click \"Submit\" and enter your GitHub repository URL\n- Packagist will automatically sync with your repository\n\n3. **Enable auto-updating**:\n\n- Go to your package page on Packagist\n- Click \"Settings\" → \"GitHub Service Hook\"\n- This ensures new releases are automatically published\n\nAfter submission, users can install your module with:\n\n```bash\ncomposer require vendor/module-name\n```\n\n**Note**: With semantic release enabled, your tags and releases are automatically created when you merge PRs with conventional commit messages (feat, fix, etc.).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🔄 Mirror to Drupal.org for Official Contrib\u003c/strong\u003e\u003c/summary\u003e\n\nFor official Drupal.org contrib modules requiring `drupal/module-name` namespacing, you can maintain your GitHub workflow while mirroring to GitLab:\n\n**Overview**: Use GitHub Actions to automatically push new tags to your Drupal.org project repository at `https://git.drupalcode.org/project/module_name`.\n\n**Requirements**:\n\n- Approved Drupal.org project page\n- SSH key or personal access token for GitLab authentication\n- GitHub Action that triggers on new releases/tags\n\n```mermaid\ngitGraph:\n    commit id: \"Initial commit\"\n    branch github\n    checkout github\n    commit id: \"feat: add feature\"\n    commit id: \"fix: bug fix\"\n    checkout main\n    merge github\n    commit id: \"v1.1.0 (auto-tag)\" tag: \"v1.1.0\"\n\n    %% Mirror action\n    branch drupal-mirror\n    checkout drupal-mirror\n    commit id: \"Mirror to GitLab\"\n    checkout main\n```\n\n**Process Flow**:\n\n1. **GitHub**: Developer workflow with PRs and semantic commits\n2. **Auto-release**: Semantic Release creates tags automatically\n3. **Mirror Action**: GitHub Action pushes code to `git.drupalcode.org`\n4. **Manual Step**: Create release on Drupal.org project page using the mirrored tag\n\n**Note**: While code mirroring can be automated, Drupal.org releases must be manually created through the project interface to generate the `drupal/module-name` Composer package.\n\n\u003c/details\u003e\n\n### 6. Clean Up Example Files\n\n- Delete `dummy.css` and `dummy.js` files - these are only included to demonstrate that the linting and code quality checks work correctly\n- These files serve no functional purpose and should be removed once you've verified the linting works\n\n## 🎁 Features Included\n\n### 🧪 Testing Infrastructure\n\n- **PHPUnit Test Suites**: Unit, Kernel, Functional, and FunctionalJavaScript tests\n- **Trivial Test Examples**: Ready-to-adapt test templates for all test types\n- **GitHub CI/CD**: Automated testing on pull requests and pushes\n- **E2E Testing**: Playwright configuration for end-to-end testing\n\n### 🔍 Code Quality Tools\n\n- **PHPStan**: Static analysis configuration (`phpstan.neon`)\n- **ESLint**: JavaScript linting (`.eslintrc.json`)\n- **Prettier**: Code formatting (`.prettierrc.json`)\n- **Pre-commit Hooks**: Automated code quality checks\n\n### 🔧 Development Tools\n\n- **GitHub Actions Workflows**:\n  - `test.yml`: Comprehensive testing pipeline\n  - `release.yml`: Release automation\n- **Git Hooks**: Automated pre-commit checks via Husky\n- **Node.js Integration**: Package management and frontend tooling\n- **Git Configuration**: Proper `.gitignore` files for Drupal modules\n\n### 🤖 AI-Friendly Configuration\n\n- **AGENTS.md**: Instructions for AI assistants working on the project\n- **Structured Documentation**: Clear patterns for AI to follow\n- **Task Management Integration**: Ready for AI task orchestration\n\n## 🧪 Testing\n\nThe template includes comprehensive testing infrastructure that'll make your tests run smoother than a freshly cached Drupal site! 🏃‍♂️\n\n### PHPUnit Tests\n\n```bash\n# Run all tests\nvendor/bin/phpunit\n\n# Run specific test suites\nvendor/bin/phpunit --testsuite=unit\nvendor/bin/phpunit --testsuite=kernel\nvendor/bin/phpunit --testsuite=functional\nvendor/bin/phpunit --testsuite=functional-javascript\n```\n\n### Code Quality Checks\n\n```bash\n# Static analysis (let PHPStan judge your code so your colleagues don't have to)\nvendor/bin/phpstan analyze\n\n# Coding standards checks and fixes (because consistency is key 🔑)\ncomposer run-script lint:check    # Check coding standards with PHPCS\ncomposer run-script lint:fix      # Fix coding standards with PHPCBF\n\n# JavaScript linting\nnpm run lint\n\n# Code formatting\nnpm run format\n```\n\n### E2E Testing\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📦 E2E Dependencies Installation\u003c/strong\u003e\u003c/summary\u003e\n\n#### Prerequisites\n\n- **Node.js**: Version 18.0.0 or higher\n- **npm**: Installed with Node.js\n- **Drupal Environment**: Running Drupal instance (local or remote)\n\n#### Step-by-Step Installation\n\n1. **Install Node.js Dependencies**\n\n   ```bash\n   # Install all npm dependencies (includes Playwright)\n   npm ci\n   ```\n\n2. **Install Playwright Browsers**\n\n   ```bash\n   # Download and install browser binaries (Chromium, Firefox, WebKit)\n   npm run e2e:install\n   ```\n\n   This command downloads approximately 300MB of browser binaries and may take a few minutes on first run.\n\n3. **Verify Installation**\n\n   ```bash\n   # Check Playwright installation\n   npx playwright --version\n\n   # List installed browsers\n   npx playwright install --dry-run\n   ```\n\n#### Troubleshooting Installation\n\n**Permission Issues on Linux/macOS:**\n\n```bash\nsudo npx playwright install-deps\n```\n\n**Network/Firewall Issues:**\n\n```bash\n# Use alternative download method\nPLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci\nnpx playwright install chromium\n```\n\n**Disk Space Issues:**\n\n- Playwright browsers require ~1GB disk space\n- Use `npx playwright install chromium` to install only Chromium (smallest footprint)\n\n\u003c/details\u003e\n\n#### Running Tests\n\n```bash\n# Run all tests\nnpm run e2e:test\n\n# Run with browser UI (for debugging)\nnpm run e2e:test:headed\n\n# Run in debug mode with step-by-step execution\nnpm run e2e:test:debug\n\n# View test reports\nnpm run e2e:report\n```\n\n## 📁 Directory Structure\n\n```\nyour_module_name/\n├── .github/workflows/          # CI/CD pipelines\n├── .claude/                   # AI assistant configuration\n├── src/                       # PHP source code\n├── tests/\n│   ├── src/                   # PHPUnit tests\n│   └── e2e/                   # Playwright E2E tests\n├── config/                    # Configuration files\n├── AGENTS.md                  # AI assistant instructions\n├── composer.json              # PHP dependencies\n├── package.json               # Node.js dependencies\n├── phpstan.neon              # Static analysis config\n└── your_module_name.info.yml  # Drupal module info\n```\n\n## ⚙️ GitHub Actions Integration\n\nThe template includes three main workflows:\n\n- **Test Pipeline**: Runs on every PR and push, executing all test suites\n- **AI Integration**: Supports AI-assisted development workflows\n- **Release Automation**: Handles versioning and releases (see step 3 in setup for permissions)\n\n\u003cdetails\u003e\n\u003csummary\u003eTroubleshooting\u003c/summary\u003e\nIf the \u003ccode\u003eTag\u003c/code\u003e action for the semantic release job is failing because of missing GitHub permissions, then navigate to \"Settings\" → \"Actions\" → \"General\" → \"Workflow permissions\" and check \u003cem\u003eRead and write permissions\u003c/em\u003e and \u003cem\u003eAllow GitHub Actions to create and approve pull requests\u003c/em\u003e.\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe0ipso%2Fgh_contrib_template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fe0ipso%2Fgh_contrib_template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe0ipso%2Fgh_contrib_template/lists"}