claude-plugin-wordpress-manager 1.8.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.claude-plugin/plugin.json +7 -3
  2. package/CHANGELOG.md +41 -0
  3. package/agents/wp-cicd-engineer.md +194 -0
  4. package/agents/wp-site-manager.md +27 -0
  5. package/docs/plans/2026-02-28-cicd-v2.0.0.md +375 -0
  6. package/docs/plans/2026-02-28-multisite-v1.9.0-design.md +258 -0
  7. package/docs/plans/2026-02-28-multisite-v1.9.0.md +1604 -0
  8. package/package.json +8 -3
  9. package/servers/wp-rest-bridge/build/tools/index.d.ts +260 -0
  10. package/servers/wp-rest-bridge/build/tools/index.js +6 -0
  11. package/servers/wp-rest-bridge/build/tools/multisite-network.d.ts +132 -0
  12. package/servers/wp-rest-bridge/build/tools/multisite-network.js +157 -0
  13. package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +150 -0
  14. package/servers/wp-rest-bridge/build/tools/multisite-sites.js +160 -0
  15. package/servers/wp-rest-bridge/build/types.d.ts +13 -0
  16. package/servers/wp-rest-bridge/build/wordpress.d.ts +19 -0
  17. package/servers/wp-rest-bridge/build/wordpress.js +10 -0
  18. package/servers/wp-rest-bridge/build/wpcli.d.ts +23 -0
  19. package/servers/wp-rest-bridge/build/wpcli.js +72 -0
  20. package/skills/wordpress-router/references/decision-tree.md +7 -3
  21. package/skills/wp-cicd/SKILL.md +119 -0
  22. package/skills/wp-cicd/references/bitbucket-pipelines-wordpress.md +142 -0
  23. package/skills/wp-cicd/references/deploy-strategies.md +164 -0
  24. package/skills/wp-cicd/references/github-actions-wordpress.md +183 -0
  25. package/skills/wp-cicd/references/gitlab-ci-wordpress.md +189 -0
  26. package/skills/wp-cicd/references/quality-gates.md +215 -0
  27. package/skills/wp-cicd/references/secrets-management.md +175 -0
  28. package/skills/wp-cicd/references/wp-env-ci.md +135 -0
  29. package/skills/wp-cicd/scripts/cicd_inspect.mjs +183 -0
  30. package/skills/wp-deploy/SKILL.md +4 -0
  31. package/skills/wp-e2e-testing/SKILL.md +4 -0
  32. package/skills/wp-multisite/SKILL.md +92 -0
  33. package/skills/wp-multisite/references/domain-mapping.md +70 -0
  34. package/skills/wp-multisite/references/migration-multisite.md +76 -0
  35. package/skills/wp-multisite/references/network-plugins.md +66 -0
  36. package/skills/wp-multisite/references/network-setup.md +69 -0
  37. package/skills/wp-multisite/references/site-management.md +67 -0
  38. package/skills/wp-multisite/references/user-roles.md +73 -0
  39. package/skills/wp-multisite/scripts/multisite_inspect.mjs +160 -0
  40. package/skills/wp-phpstan/SKILL.md +4 -0
  41. package/skills/wp-security/SKILL.md +4 -0
  42. package/skills/wp-wpcli-and-ops/SKILL.md +4 -0
@@ -0,0 +1,142 @@
1
+ # Bitbucket Pipelines for WordPress
2
+
3
+ Step-based pipeline configuration for WordPress projects hosted on Bitbucket.
4
+
5
+ ## Full Pipeline Template
6
+
7
+ ```yaml
8
+ image: php:8.2-cli
9
+
10
+ definitions:
11
+ caches:
12
+ composer: ~/.composer/cache
13
+ services:
14
+ mysql:
15
+ image: mysql:8.0
16
+ variables:
17
+ MYSQL_ROOT_PASSWORD: root
18
+ MYSQL_DATABASE: wordpress_tests
19
+ docker:
20
+ memory: 2048
21
+
22
+ pipelines:
23
+ default:
24
+ - parallel:
25
+ - step:
26
+ name: PHPCS Lint
27
+ caches:
28
+ - composer
29
+ script:
30
+ - apt-get update && apt-get install -y unzip git
31
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
32
+ - composer global require --dev wp-coding-standards/wpcs:"^3.0"
33
+ - composer global exec phpcs -- --config-set installed_paths $(composer global config home)/vendor/wp-coding-standards/wpcs
34
+ - composer global exec phpcs -- --standard=WordPress .
35
+
36
+ - step:
37
+ name: PHPStan
38
+ caches:
39
+ - composer
40
+ script:
41
+ - apt-get update && apt-get install -y unzip git
42
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
43
+ - composer install --no-interaction --prefer-dist
44
+ - vendor/bin/phpstan analyse
45
+
46
+ - parallel:
47
+ - step:
48
+ name: PHPUnit
49
+ caches:
50
+ - composer
51
+ services:
52
+ - mysql
53
+ script:
54
+ - apt-get update && apt-get install -y unzip git default-mysql-client
55
+ - docker-php-ext-install mysqli
56
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
57
+ - composer install --no-interaction --prefer-dist
58
+ - bash bin/install-wp-tests.sh wordpress_tests root root 127.0.0.1 latest
59
+ - vendor/bin/phpunit
60
+
61
+ - step:
62
+ name: Jest Unit Tests
63
+ image: node:20
64
+ caches:
65
+ - node
66
+ script:
67
+ - npm ci
68
+ - npx wp-scripts test-unit-js --coverage
69
+
70
+ - step:
71
+ name: E2E Tests
72
+ image: node:20
73
+ size: 2x
74
+ services:
75
+ - docker
76
+ caches:
77
+ - node
78
+ script:
79
+ - npm ci
80
+ - npm run build
81
+ - npx wp-env start
82
+ - npx playwright install chromium --with-deps
83
+ - npx playwright test
84
+ artifacts:
85
+ - playwright-report/**
86
+
87
+ branches:
88
+ main:
89
+ - parallel:
90
+ - step:
91
+ name: PHPCS Lint
92
+ caches:
93
+ - composer
94
+ script:
95
+ - apt-get update && apt-get install -y unzip git
96
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
97
+ - composer global require --dev wp-coding-standards/wpcs:"^3.0"
98
+ - composer global exec phpcs -- --config-set installed_paths $(composer global config home)/vendor/wp-coding-standards/wpcs
99
+ - composer global exec phpcs -- --standard=WordPress .
100
+ - step:
101
+ name: PHPStan
102
+ caches:
103
+ - composer
104
+ script:
105
+ - apt-get update && apt-get install -y unzip git
106
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
107
+ - composer install --no-interaction --prefer-dist
108
+ - vendor/bin/phpstan analyse
109
+ - step:
110
+ name: Deploy to Production
111
+ deployment: production
112
+ trigger: manual
113
+ script:
114
+ - pipe: atlassian/ssh-run:0.8.1
115
+ variables:
116
+ SSH_USER: $SSH_USER
117
+ SERVER: $SSH_HOST
118
+ COMMAND: |
119
+ cd /var/www/html/wp-content/plugins/my-plugin
120
+ git pull origin main
121
+ composer install --no-dev --no-interaction
122
+ wp cache flush
123
+ ```
124
+
125
+ ## Repository Variables
126
+
127
+ Set in Repository Settings > Pipelines > Repository variables:
128
+
129
+ | Variable | Secured |
130
+ |----------|---------|
131
+ | `SSH_USER` | No |
132
+ | `SSH_HOST` | No |
133
+ | `SSH_PRIVATE_KEY` | Yes |
134
+
135
+ ## Tips
136
+
137
+ - Use `parallel` keyword for concurrent steps (lint + static analysis)
138
+ - Use `size: 2x` for memory-intensive steps like E2E with Docker
139
+ - Use `trigger: manual` for production deployment approval
140
+ - Use `deployment: production` to track deploy history
141
+ - Use Bitbucket Pipes for common tasks (SSH, S3, Slack notifications)
142
+ - Bitbucket has a 120-minute timeout per step — watch for slow E2E suites
@@ -0,0 +1,164 @@
1
+ # Deployment Strategies for WordPress
2
+
3
+ Strategies for deploying WordPress plugins, themes, and full sites via CI/CD pipelines. Each strategy balances risk, downtime, and complexity.
4
+
5
+ ## Direct Push
6
+
7
+ Simplest strategy — deploy directly to the server.
8
+
9
+ ```bash
10
+ # Via SSH
11
+ ssh deploy@server "cd /var/www/html/wp-content/plugins/my-plugin && git pull origin main"
12
+
13
+ # Via rsync
14
+ rsync -avz --delete --exclude='.git' --exclude='node_modules' ./ deploy@server:/path/to/plugin/
15
+ ```
16
+
17
+ **Pros:** Simple, fast, no extra infrastructure.
18
+ **Cons:** No rollback, brief downtime during deploy, risk of partial deploy.
19
+ **Use when:** Development/staging, low-traffic sites.
20
+
21
+ ## Blue-Green Deployment
22
+
23
+ Maintain two identical environments. Deploy to inactive, then swap.
24
+
25
+ ```
26
+ 1. Deploy to GREEN (inactive)
27
+ 2. Run smoke tests on GREEN
28
+ 3. Swap router: GREEN → active, BLUE → inactive
29
+ 4. If issues: swap back instantly
30
+ ```
31
+
32
+ WordPress implementation:
33
+ ```bash
34
+ # Deploy to staging directory
35
+ rsync -avz ./ deploy@server:/var/www/green/wp-content/plugins/my-plugin/
36
+
37
+ # Run smoke tests
38
+ curl -f https://green.example.com/wp-json/ || exit 1
39
+
40
+ # Swap symlink
41
+ ssh deploy@server "ln -sfn /var/www/green /var/www/html"
42
+
43
+ # Flush caches
44
+ ssh deploy@server "cd /var/www/html && wp cache flush && wp rewrite flush"
45
+ ```
46
+
47
+ **Pros:** Zero downtime, instant rollback.
48
+ **Cons:** Requires double infrastructure, database must be shared.
49
+ **Use when:** Production with uptime requirements.
50
+
51
+ ## Rolling Deployment
52
+
53
+ Deploy one server at a time behind a load balancer.
54
+
55
+ ```
56
+ 1. Remove server-1 from load balancer
57
+ 2. Deploy to server-1
58
+ 3. Healthcheck server-1
59
+ 4. Add server-1 back to load balancer
60
+ 5. Repeat for server-2, server-3...
61
+ ```
62
+
63
+ **Pros:** Zero downtime, gradual rollout.
64
+ **Cons:** Requires load balancer, mixed versions briefly.
65
+ **Use when:** Multi-server setups.
66
+
67
+ ## Canary Deployment
68
+
69
+ Deploy to a small percentage of traffic first.
70
+
71
+ ```
72
+ 1. Deploy to canary server (5% traffic)
73
+ 2. Monitor error rates and performance
74
+ 3. If healthy: roll out to remaining 95%
75
+ 4. If issues: route all traffic away from canary
76
+ ```
77
+
78
+ **Pros:** Lowest risk, real-world validation.
79
+ **Cons:** Requires traffic routing infrastructure.
80
+ **Use when:** High-traffic production, risky changes.
81
+
82
+ ## Manual Approval Gate
83
+
84
+ CI runs all tests, then waits for human approval before deploying.
85
+
86
+ GitHub Actions:
87
+ ```yaml
88
+ deploy:
89
+ needs: [test]
90
+ environment: production # Requires manual approval in GitHub settings
91
+ steps:
92
+ - run: ./deploy.sh
93
+ ```
94
+
95
+ GitLab CI:
96
+ ```yaml
97
+ deploy:
98
+ when: manual
99
+ environment:
100
+ name: production
101
+ ```
102
+
103
+ **Pros:** Human review before production.
104
+ **Cons:** Adds latency to deploy cycle.
105
+ **Use when:** Always recommended for production.
106
+
107
+ ## WordPress-Specific Considerations
108
+
109
+ ### Maintenance Mode
110
+
111
+ For deploys that change database schema or run migrations:
112
+
113
+ ```bash
114
+ # Enable maintenance mode
115
+ ssh deploy@server "cd /var/www/html && wp maintenance-mode activate"
116
+
117
+ # Deploy
118
+ rsync -avz ./ deploy@server:/var/www/html/wp-content/plugins/my-plugin/
119
+
120
+ # Run migrations (if any)
121
+ ssh deploy@server "cd /var/www/html && wp plugin activate my-plugin"
122
+
123
+ # Disable maintenance mode
124
+ ssh deploy@server "cd /var/www/html && wp maintenance-mode deactivate"
125
+ ```
126
+
127
+ ### Post-Deploy Cache Flush
128
+
129
+ Always flush caches after deployment:
130
+
131
+ ```bash
132
+ wp cache flush # Object cache
133
+ wp rewrite flush # Permalink rewrite rules
134
+ wp transient delete --all # Transients
135
+ ```
136
+
137
+ If using a caching plugin (WP Super Cache, W3 Total Cache):
138
+ ```bash
139
+ wp w3-total-cache flush all # W3TC
140
+ wp super-cache flush # WP Super Cache
141
+ ```
142
+
143
+ ### Database Migrations
144
+
145
+ For plugins with custom tables:
146
+ ```bash
147
+ # Before deploy: backup
148
+ wp db export pre-deploy-backup.sql
149
+
150
+ # After deploy: run activation hooks that create/update tables
151
+ wp plugin deactivate my-plugin && wp plugin activate my-plugin
152
+ ```
153
+
154
+ ## Choosing a Strategy
155
+
156
+ | Factor | Direct Push | Blue-Green | Rolling | Canary |
157
+ |--------|------------|------------|---------|--------|
158
+ | Downtime | Brief | Zero | Zero | Zero |
159
+ | Rollback speed | Slow | Instant | Medium | Fast |
160
+ | Infrastructure cost | Low | 2x | Same | Same + routing |
161
+ | Complexity | Low | Medium | High | High |
162
+ | Risk | High | Low | Medium | Low |
163
+
164
+ **Recommendation:** Start with Direct Push + Manual Approval for staging. Move to Blue-Green for production when uptime matters.
@@ -0,0 +1,183 @@
1
+ # GitHub Actions for WordPress
2
+
3
+ Complete workflow templates for WordPress plugin and theme CI/CD pipelines.
4
+
5
+ ## Full Pipeline Template
6
+
7
+ ```yaml
8
+ name: WordPress CI
9
+
10
+ on:
11
+ push:
12
+ branches: [main, develop]
13
+ pull_request:
14
+ branches: [main]
15
+
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: true
19
+
20
+ jobs:
21
+ lint:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+ - uses: shivammathur/setup-php@v2
26
+ with:
27
+ php-version: '8.2'
28
+ tools: cs2pr, phpcs
29
+ - name: Install PHPCS standards
30
+ run: |
31
+ composer global require --dev wp-coding-standards/wpcs:"^3.0"
32
+ phpcs --config-set installed_paths $(composer global config home)/vendor/wp-coding-standards/wpcs
33
+ - name: Run PHPCS
34
+ run: phpcs --standard=WordPress --report=checkstyle . | cs2pr
35
+
36
+ static-analysis:
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - uses: shivammathur/setup-php@v2
41
+ with:
42
+ php-version: '8.2'
43
+ - name: Install dependencies
44
+ run: composer install --no-interaction --prefer-dist
45
+ - name: Run PHPStan
46
+ run: vendor/bin/phpstan analyse --error-format=github
47
+
48
+ test-php:
49
+ runs-on: ubuntu-latest
50
+ strategy:
51
+ matrix:
52
+ php: ['7.4', '8.0', '8.2', '8.3']
53
+ wp: ['latest']
54
+ include:
55
+ - php: '8.2'
56
+ wp: 'nightly'
57
+ fail-fast: false
58
+ services:
59
+ mysql:
60
+ image: mysql:8.0
61
+ env:
62
+ MYSQL_ROOT_PASSWORD: root
63
+ MYSQL_DATABASE: wordpress_tests
64
+ ports: ['3306:3306']
65
+ options: >-
66
+ --health-cmd="mysqladmin ping"
67
+ --health-interval=10s
68
+ --health-timeout=5s
69
+ --health-retries=3
70
+ steps:
71
+ - uses: actions/checkout@v4
72
+ - uses: shivammathur/setup-php@v2
73
+ with:
74
+ php-version: ${{ matrix.php }}
75
+ extensions: mysqli
76
+ coverage: xdebug
77
+ - name: Install WP Test Suite
78
+ run: bash bin/install-wp-tests.sh wordpress_tests root root 127.0.0.1 ${{ matrix.wp }}
79
+ - name: Install dependencies
80
+ run: composer install --no-interaction --prefer-dist
81
+ - name: Run PHPUnit
82
+ run: vendor/bin/phpunit --coverage-clover=coverage.xml
83
+ - name: Upload coverage
84
+ if: matrix.php == '8.2' && matrix.wp == 'latest'
85
+ uses: codecov/codecov-action@v4
86
+ with:
87
+ file: coverage.xml
88
+
89
+ test-e2e:
90
+ runs-on: ubuntu-latest
91
+ steps:
92
+ - uses: actions/checkout@v4
93
+ - uses: actions/setup-node@v4
94
+ with:
95
+ node-version: '20'
96
+ cache: 'npm'
97
+ - name: Install dependencies
98
+ run: npm ci
99
+ - name: Build
100
+ run: npm run build
101
+ - name: Start wp-env
102
+ run: npx wp-env start
103
+ - name: Install Playwright browsers
104
+ run: npx playwright install chromium --with-deps
105
+ - name: Run E2E tests
106
+ run: npx playwright test
107
+ - name: Upload artifacts
108
+ if: failure()
109
+ uses: actions/upload-artifact@v4
110
+ with:
111
+ name: playwright-report
112
+ path: playwright-report/
113
+ retention-days: 7
114
+
115
+ test-js:
116
+ runs-on: ubuntu-latest
117
+ steps:
118
+ - uses: actions/checkout@v4
119
+ - uses: actions/setup-node@v4
120
+ with:
121
+ node-version: '20'
122
+ cache: 'npm'
123
+ - name: Install dependencies
124
+ run: npm ci
125
+ - name: Run Jest
126
+ run: npx wp-scripts test-unit-js --coverage
127
+
128
+ deploy:
129
+ needs: [lint, static-analysis, test-php, test-e2e, test-js]
130
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
131
+ runs-on: ubuntu-latest
132
+ environment: production
133
+ steps:
134
+ - uses: actions/checkout@v4
135
+ - name: Deploy via SSH
136
+ uses: appleboy/ssh-action@v1
137
+ with:
138
+ host: ${{ secrets.SSH_HOST }}
139
+ username: ${{ secrets.SSH_USER }}
140
+ key: ${{ secrets.SSH_PRIVATE_KEY }}
141
+ script: |
142
+ cd /var/www/html/wp-content/plugins/my-plugin
143
+ git pull origin main
144
+ composer install --no-dev --no-interaction
145
+ wp cache flush
146
+ ```
147
+
148
+ ## Caching Strategies
149
+
150
+ ```yaml
151
+ # Composer cache
152
+ - name: Get Composer cache dir
153
+ id: composer-cache
154
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
155
+ - uses: actions/cache@v4
156
+ with:
157
+ path: ${{ steps.composer-cache.outputs.dir }}
158
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
159
+
160
+ # npm cache (handled by setup-node cache: 'npm')
161
+
162
+ # wp-env Docker image cache
163
+ - name: Cache Docker images
164
+ uses: ScribeMD/docker-cache@0.5.0
165
+ with:
166
+ key: docker-${{ runner.os }}-${{ hashFiles('.wp-env.json') }}
167
+ ```
168
+
169
+ ## Required Status Checks
170
+
171
+ Configure in repository Settings > Branches > Branch protection:
172
+
173
+ 1. Require status checks: `lint`, `static-analysis`, `test-php`, `test-e2e`
174
+ 2. Require branches to be up to date
175
+ 3. Require pull request reviews before merging
176
+
177
+ ## Tips
178
+
179
+ - Use `concurrency` to cancel superseded runs on the same branch
180
+ - Use `fail-fast: false` in matrix to see all failures, not just the first
181
+ - Upload Playwright reports as artifacts for debugging
182
+ - Use GitHub Environments for deploy approval gates
183
+ - Cache Docker images for wp-env to speed up E2E jobs
@@ -0,0 +1,189 @@
1
+ # GitLab CI for WordPress
2
+
3
+ Multi-stage pipeline configuration for WordPress plugin and theme projects on GitLab.
4
+
5
+ ## Full Pipeline Template
6
+
7
+ ```yaml
8
+ stages:
9
+ - lint
10
+ - test
11
+ - build
12
+ - deploy
13
+
14
+ variables:
15
+ MYSQL_ROOT_PASSWORD: root
16
+ MYSQL_DATABASE: wordpress_tests
17
+ WP_VERSION: latest
18
+ PHP_VERSION: "8.2"
19
+
20
+ # Cache Composer and npm dependencies
21
+ cache:
22
+ paths:
23
+ - vendor/
24
+ - node_modules/
25
+ - .npm/
26
+
27
+ # ---------------------------------------------------------------------------
28
+ # Lint stage
29
+ # ---------------------------------------------------------------------------
30
+
31
+ phpcs:
32
+ stage: lint
33
+ image: php:${PHP_VERSION}-cli
34
+ before_script:
35
+ - apt-get update && apt-get install -y unzip git
36
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
37
+ - composer global require --dev wp-coding-standards/wpcs:"^3.0"
38
+ - composer global exec phpcs -- --config-set installed_paths $(composer global config home)/vendor/wp-coding-standards/wpcs
39
+ script:
40
+ - composer global exec phpcs -- --standard=WordPress .
41
+ allow_failure: false
42
+
43
+ # ---------------------------------------------------------------------------
44
+ # Test stage
45
+ # ---------------------------------------------------------------------------
46
+
47
+ phpstan:
48
+ stage: test
49
+ image: php:${PHP_VERSION}-cli
50
+ before_script:
51
+ - apt-get update && apt-get install -y unzip git
52
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
53
+ - composer install --no-interaction --prefer-dist
54
+ script:
55
+ - vendor/bin/phpstan analyse
56
+
57
+ phpunit:
58
+ stage: test
59
+ image: php:${PHP_VERSION}-cli
60
+ services:
61
+ - name: mysql:8.0
62
+ alias: mysql
63
+ variables:
64
+ MYSQL_HOST: mysql
65
+ before_script:
66
+ - apt-get update && apt-get install -y unzip git default-mysql-client
67
+ - docker-php-ext-install mysqli
68
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
69
+ - composer install --no-interaction --prefer-dist
70
+ - bash bin/install-wp-tests.sh ${MYSQL_DATABASE} root ${MYSQL_ROOT_PASSWORD} mysql ${WP_VERSION}
71
+ script:
72
+ - vendor/bin/phpunit --coverage-text
73
+ parallel:
74
+ matrix:
75
+ - PHP_VERSION: ['7.4', '8.0', '8.2', '8.3']
76
+
77
+ jest:
78
+ stage: test
79
+ image: node:20
80
+ before_script:
81
+ - npm ci --cache .npm --prefer-offline
82
+ script:
83
+ - npx wp-scripts test-unit-js --coverage
84
+
85
+ e2e:
86
+ stage: test
87
+ image: node:20
88
+ services:
89
+ - name: docker:dind
90
+ alias: docker
91
+ variables:
92
+ DOCKER_HOST: tcp://docker:2376
93
+ DOCKER_TLS_CERTDIR: "/certs"
94
+ before_script:
95
+ - npm ci --cache .npm --prefer-offline
96
+ - npm run build
97
+ - npx wp-env start
98
+ - npx playwright install chromium --with-deps
99
+ script:
100
+ - npx playwright test
101
+ artifacts:
102
+ when: on_failure
103
+ paths:
104
+ - playwright-report/
105
+ expire_in: 7 days
106
+
107
+ # ---------------------------------------------------------------------------
108
+ # Build stage
109
+ # ---------------------------------------------------------------------------
110
+
111
+ build:
112
+ stage: build
113
+ image: node:20
114
+ before_script:
115
+ - npm ci --cache .npm --prefer-offline
116
+ script:
117
+ - npm run build
118
+ artifacts:
119
+ paths:
120
+ - build/
121
+ expire_in: 1 hour
122
+ only:
123
+ - main
124
+ - tags
125
+
126
+ # ---------------------------------------------------------------------------
127
+ # Deploy stage
128
+ # ---------------------------------------------------------------------------
129
+
130
+ deploy_staging:
131
+ stage: deploy
132
+ image: alpine:latest
133
+ environment:
134
+ name: staging
135
+ url: https://staging.example.com
136
+ before_script:
137
+ - apk add --no-cache openssh-client rsync
138
+ - eval $(ssh-agent -s)
139
+ - echo "$SSH_PRIVATE_KEY" | ssh-add -
140
+ - mkdir -p ~/.ssh && chmod 700 ~/.ssh
141
+ - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
142
+ script:
143
+ - rsync -avz --delete --exclude='.git' ./ $SSH_USER@$SSH_HOST:/var/www/staging/wp-content/plugins/my-plugin/
144
+ - ssh $SSH_USER@$SSH_HOST "cd /var/www/staging && wp cache flush"
145
+ only:
146
+ - develop
147
+ dependencies:
148
+ - build
149
+
150
+ deploy_production:
151
+ stage: deploy
152
+ image: alpine:latest
153
+ environment:
154
+ name: production
155
+ url: https://example.com
156
+ when: manual
157
+ before_script:
158
+ - apk add --no-cache openssh-client rsync
159
+ - eval $(ssh-agent -s)
160
+ - echo "$SSH_PRIVATE_KEY" | ssh-add -
161
+ - mkdir -p ~/.ssh && chmod 700 ~/.ssh
162
+ - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
163
+ script:
164
+ - rsync -avz --delete --exclude='.git' ./ $SSH_USER@$SSH_HOST:/var/www/html/wp-content/plugins/my-plugin/
165
+ - ssh $SSH_USER@$SSH_HOST "cd /var/www/html && wp cache flush && wp rewrite flush"
166
+ only:
167
+ - main
168
+ dependencies:
169
+ - build
170
+ ```
171
+
172
+ ## GitLab CI/CD Variables
173
+
174
+ Set in Settings > CI/CD > Variables:
175
+
176
+ | Variable | Type | Protected | Masked |
177
+ |----------|------|-----------|--------|
178
+ | `SSH_PRIVATE_KEY` | Variable | Yes | Yes |
179
+ | `SSH_KNOWN_HOSTS` | Variable | Yes | No |
180
+ | `SSH_USER` | Variable | Yes | No |
181
+ | `SSH_HOST` | Variable | Yes | No |
182
+
183
+ ## Tips
184
+
185
+ - Use `parallel: matrix` for PHP version matrix testing
186
+ - Use `when: manual` for production deploy (approval gate)
187
+ - Use `dependencies` to pass artifacts between stages
188
+ - Use Docker-in-Docker service for wp-env in E2E tests
189
+ - Set `allow_failure: true` on nightly WP version tests