@codigodoleo/wp-kit 3.1.1 → 3.3.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 (112) hide show
  1. package/lib/commands/init.js +19 -10
  2. package/lib/config/versions.js +5 -5
  3. package/lib/core/infer-ci-capabilities.js +17 -0
  4. package/lib/prompts/index.js +27 -17
  5. package/lib/utils/git.js +50 -13
  6. package/modules/blank-theme/index.js +71 -0
  7. package/modules/blank-theme/lint/.prettierrc.json +12 -0
  8. package/modules/blank-theme/lint/.stylelintrc.json +7 -0
  9. package/modules/{lint → blank-theme/lint}/eslint.config.mjs +2 -8
  10. package/modules/blank-theme/lint/pint.json +11 -0
  11. package/modules/blank-theme/prompts.js +36 -0
  12. package/modules/blank-theme/templates/.lando.yml.hbs +26 -0
  13. package/modules/blank-theme/templates/functions.php.hbs +46 -0
  14. package/modules/blank-theme/templates/package.json.hbs +16 -0
  15. package/modules/blank-theme/templates/style.css.hbs +7 -0
  16. package/modules/blank-theme/templates/vite.config.js.hbs +23 -0
  17. package/modules/deploy/.github/workflows/deploy-docker.yml +104 -0
  18. package/modules/deploy/.github/workflows/deploy-ssh.yml +128 -0
  19. package/modules/deploy/.github/workflows/release.yml +57 -0
  20. package/modules/deploy/index.js +77 -0
  21. package/modules/deploy/prompts.js +1 -3
  22. package/modules/deploy/templates/.github/workflows/ci.yml.hbs +29 -1
  23. package/modules/deploy/templates/.gitlab/ci/deploy-docker.yml.hbs +35 -0
  24. package/modules/deploy/templates/.gitlab/ci/deploy-ssh.yml.hbs +83 -0
  25. package/modules/deploy/templates/.gitlab/ci/lint-blank-theme.yml.hbs +35 -0
  26. package/modules/deploy/templates/.gitlab/ci/lint-mu-plugin.yml.hbs +19 -0
  27. package/modules/deploy/templates/.gitlab/ci/lint-plugin.yml.hbs +19 -0
  28. package/modules/deploy/templates/.gitlab/ci/lint-sage.yml.hbs +47 -0
  29. package/modules/deploy/templates/.gitlab/ci/release.yml.hbs +26 -0
  30. package/modules/git/.husky/commit-msg +8 -4
  31. package/modules/git/.husky/pre-commit +0 -3
  32. package/modules/git/templates/package.json.hbs +4 -4
  33. package/modules/git/templates/workspace.json.hbs +1 -1
  34. package/modules/lint/.commitlintrc.json +21 -0
  35. package/modules/lint/.prettierignore +15 -25
  36. package/modules/lint/.prettierrc.json +5 -16
  37. package/modules/lint/index.js +75 -8
  38. package/modules/lint/prompts.js +1 -8
  39. package/modules/lint/templates/.lando.yml.hbs +3 -8
  40. package/modules/lint/templates/package.json.hbs +4 -4
  41. package/modules/lint/templates/workspace.json.hbs +3 -3
  42. package/modules/mu-plugin/index.js +49 -0
  43. package/modules/mu-plugin/lint/.prettierrc.json +7 -0
  44. package/modules/mu-plugin/lint/eslint.config.mjs +30 -0
  45. package/modules/mu-plugin/lint/pint.json +11 -0
  46. package/modules/mu-plugin/prompts.js +29 -0
  47. package/modules/mu-plugin/templates/.lando.yml.hbs +15 -0
  48. package/modules/mu-plugin/templates/composer.json.hbs +14 -0
  49. package/modules/mu-plugin/templates/plugin.php.hbs +15 -0
  50. package/modules/php/templates/composer.json.hbs +15 -1
  51. package/modules/plugin/index.js +45 -0
  52. package/modules/plugin/lint/.prettierrc.json +7 -0
  53. package/modules/plugin/lint/eslint.config.mjs +30 -0
  54. package/modules/plugin/lint/pint.json +11 -0
  55. package/modules/plugin/prompts.js +29 -0
  56. package/modules/plugin/templates/.lando.yml.hbs +15 -0
  57. package/modules/plugin/templates/composer.json.hbs +14 -0
  58. package/modules/plugin/templates/plugin.php.hbs +15 -0
  59. package/modules/sage/index.js +139 -15
  60. package/modules/sage/lint/.prettierrc.json +12 -0
  61. package/modules/sage/lint/.stylelintrc.json +7 -0
  62. package/modules/sage/lint/eslint.config.mjs +30 -0
  63. package/modules/sage/lint/pint.json +11 -0
  64. package/modules/sage/prompts.js +22 -1
  65. package/modules/sage/templates/.devcontainer/devcontainer.json.hbs +7 -0
  66. package/modules/sage/templates/.devcontainer/docker-compose.override.yml.hbs +6 -0
  67. package/modules/sage/templates/.devcontainer/post-create.sh.hbs +11 -0
  68. package/modules/sage/templates/.lando.yml.hbs +43 -45
  69. package/modules/sage/templates/server/cmd/setup-sage-node.sh.hbs +23 -0
  70. package/modules/sage/templates/server/cmd/setup-sage-php.sh.hbs +24 -0
  71. package/modules/sage/templates/theme/app/Blocks/.gitkeep.hbs +0 -0
  72. package/modules/sage/templates/theme/app/Fields/.gitkeep.hbs +0 -0
  73. package/modules/sage/templates/theme/composer.json.hbs +25 -3
  74. package/modules/sage/templates/theme/package.json.hbs +15 -3
  75. package/modules/sage/templates/theme/resources/views/blocks/.gitkeep.hbs +0 -0
  76. package/modules/sage/templates/theme/vite.config.js.hbs +55 -13
  77. package/modules/sage/templates/workspace.json.hbs +94 -6
  78. package/modules/skills/index.js +18 -0
  79. package/modules/skills/prompts.js +21 -0
  80. package/modules/test/index.js +19 -0
  81. package/modules/test/prompts.js +8 -0
  82. package/modules/test/templates/composer.json.hbs +16 -0
  83. package/modules/test/templates/package.json.hbs +11 -0
  84. package/modules/test/templates/playwright.config.js.hbs +29 -0
  85. package/modules/test/tests/Pest.php +39 -0
  86. package/modules/test/tests/SmokeTest.php +15 -0
  87. package/modules/test/tests/e2e/example.spec.js +11 -0
  88. package/modules/test/tests/e2e/helpers/loginHelper.js +40 -0
  89. package/package.json +1 -1
  90. package/templates/.devcontainer/Dockerfile.hbs +24 -0
  91. package/templates/.devcontainer/config/nginx.conf +23 -0
  92. package/templates/.devcontainer/config/nginx.conf.hbs +23 -0
  93. package/templates/.devcontainer/devcontainer.json.hbs +29 -0
  94. package/templates/.devcontainer/docker-compose.yml.hbs +73 -0
  95. package/templates/.devcontainer/setup.sh.hbs +17 -0
  96. package/templates/.env.hbs +38 -15
  97. package/templates/.gitignore.hbs +84 -13
  98. package/templates/.lando.yml.hbs +61 -17
  99. package/templates/README.md.hbs +23 -7
  100. package/templates/composer.json.hbs +60 -12
  101. package/templates/package.json.hbs +0 -2
  102. package/templates/server/cmd/install-wp.sh.hbs +54 -43
  103. package/templates/server/cmd/setup-node.sh.hbs +11 -0
  104. package/templates/server/cmd/setup-php.sh.hbs +14 -0
  105. package/templates/server/www/vhosts.conf.hbs +54 -17
  106. package/templates/workspace.json.hbs +57 -1
  107. package/templates/wp-cli.yml.hbs +1 -0
  108. package/modules/lint/.eslintignore +0 -36
  109. package/modules/lint/.eslintrc.json +0 -8
  110. package/modules/lint/.stylelintignore +0 -19
  111. package/modules/lint/.stylelintrc.json +0 -9
  112. package/modules/lint/pint.json +0 -26
@@ -11,10 +11,24 @@
11
11
  "tasks": {
12
12
  "tasks": [
13
13
  {
14
- "label": "🏗️ Theme: Build Assets",
14
+ "label": "🛶 Lando: theme-bootstrap",
15
15
  "type": "shell",
16
16
  "command": "lando",
17
- "args": ["yarn", "build"],
17
+ "args": ["theme-bootstrap"],
18
+ "group": "build",
19
+ "presentation": {
20
+ "echo": true,
21
+ "reveal": "always",
22
+ "focus": false,
23
+ "panel": "shared"
24
+ },
25
+ "problemMatcher": []
26
+ },
27
+ {
28
+ "label": "🛶 Lando: theme-build",
29
+ "type": "shell",
30
+ "command": "lando",
31
+ "args": ["theme-build"],
18
32
  "options": {
19
33
  "cwd": "${workspaceFolder}/content/themes/{{projectName}}"
20
34
  },
@@ -28,10 +42,10 @@
28
42
  "problemMatcher": []
29
43
  },
30
44
  {
31
- "label": "👀 Theme: Watch Assets",
45
+ "label": "🛶 Lando: theme-dev",
32
46
  "type": "shell",
33
47
  "command": "lando",
34
- "args": ["yarn", "dev"],
48
+ "args": ["theme-dev"],
35
49
  "options": {
36
50
  "cwd": "${workspaceFolder}/content/themes/{{projectName}}"
37
51
  },
@@ -46,10 +60,27 @@
46
60
  "problemMatcher": []
47
61
  },
48
62
  {
49
- "label": "📦 Theme: Composer Install",
63
+ "label": "🛶 Lando: theme-lint",
64
+ "type": "shell",
65
+ "command": "lando",
66
+ "args": ["theme-lint"],
67
+ "options": {
68
+ "cwd": "${workspaceFolder}/content/themes/{{projectName}}"
69
+ },
70
+ "group": "build",
71
+ "presentation": {
72
+ "echo": true,
73
+ "reveal": "always",
74
+ "focus": false,
75
+ "panel": "shared"
76
+ },
77
+ "problemMatcher": []
78
+ },
79
+ {
80
+ "label": "🛶 Lando: acorn",
50
81
  "type": "shell",
51
82
  "command": "lando",
52
- "args": ["composer", "install"],
83
+ "args": ["acorn", "make:component", "ExampleBlock"],
53
84
  "options": {
54
85
  "cwd": "${workspaceFolder}/content/themes/{{projectName}}"
55
86
  },
@@ -61,6 +92,63 @@
61
92
  "panel": "shared"
62
93
  },
63
94
  "problemMatcher": []
95
+ },
96
+ {
97
+ "label": "🐳 Devcontainer: theme-build",
98
+ "type": "shell",
99
+ "command": "docker",
100
+ "args": ["compose", "-f", ".devcontainer/docker-compose.yml", "-f", ".devcontainer/docker-compose.override.yml", "exec", "wordpress", "bash", "-lc", "cd /workspace/content/themes/{{projectName}} && yarn build"],
101
+ "group": "build",
102
+ "presentation": {
103
+ "echo": true,
104
+ "reveal": "always",
105
+ "focus": false,
106
+ "panel": "shared"
107
+ },
108
+ "problemMatcher": []
109
+ },
110
+ {
111
+ "label": "🐳 Devcontainer: theme-dev",
112
+ "type": "shell",
113
+ "command": "docker",
114
+ "args": ["compose", "-f", ".devcontainer/docker-compose.yml", "-f", ".devcontainer/docker-compose.override.yml", "exec", "wordpress", "bash", "-lc", "cd /workspace/content/themes/{{projectName}} && yarn dev"],
115
+ "group": "build",
116
+ "isBackground": true,
117
+ "presentation": {
118
+ "echo": true,
119
+ "reveal": "always",
120
+ "focus": false,
121
+ "panel": "shared"
122
+ },
123
+ "problemMatcher": []
124
+ },
125
+ {
126
+ "label": "🐳 Devcontainer: theme-lint",
127
+ "type": "shell",
128
+ "command": "docker",
129
+ "args": ["compose", "-f", ".devcontainer/docker-compose.yml", "-f", ".devcontainer/docker-compose.override.yml", "exec", "wordpress", "bash", "-lc", "cd /workspace/content/themes/{{projectName}} && yarn lint"],
130
+ "group": "build",
131
+ "presentation": {
132
+ "echo": true,
133
+ "reveal": "always",
134
+ "focus": false,
135
+ "panel": "shared"
136
+ },
137
+ "problemMatcher": []
138
+ },
139
+ {
140
+ "label": "🐳 Devcontainer: acorn",
141
+ "type": "shell",
142
+ "command": "docker",
143
+ "args": ["compose", "-f", ".devcontainer/docker-compose.yml", "-f", ".devcontainer/docker-compose.override.yml", "exec", "wordpress", "bash", "-lc", "cd /workspace/content/themes/{{projectName}} && wp acorn make:component ExampleBlock"],
144
+ "group": "build",
145
+ "presentation": {
146
+ "echo": true,
147
+ "reveal": "always",
148
+ "focus": false,
149
+ "panel": "shared"
150
+ },
151
+ "problemMatcher": []
64
152
  }
65
153
  ]
66
154
  }
@@ -0,0 +1,18 @@
1
+ import { installSuperpowersSage } from '../../lib/utils/git.js';
2
+ import { log, color } from '../../lib/utils/logger.js';
3
+
4
+ export async function setupModule(context, _generator) {
5
+ if (!context.enable_skills) {
6
+ log(color.orange, '[skills] Instalação de skills desabilitada. Pulando.');
7
+ return;
8
+ }
9
+
10
+ const targets = context.skills_targets ?? ['claude'];
11
+
12
+ if (targets.length === 0) {
13
+ log(color.orange, '[skills] Nenhum destino selecionado. Pulando.');
14
+ return;
15
+ }
16
+
17
+ await installSuperpowersSage(context.cwd, targets);
18
+ }
@@ -0,0 +1,21 @@
1
+ export default [
2
+ {
3
+ type: 'confirm',
4
+ name: 'enable_skills',
5
+ message: 'Instalar AI skills (superpowers-sage) no projeto?',
6
+ default: true,
7
+ },
8
+ {
9
+ type: 'checkbox',
10
+ name: 'skills_targets',
11
+ message: 'Onde instalar as skills?',
12
+ choices: [
13
+ { name: 'Claude Code → .claude/', value: 'claude' },
14
+ { name: 'Cursor → .cursor/', value: 'cursor' },
15
+ { name: 'Agnóstico → .ai/', value: 'ai' },
16
+ ],
17
+ default: ['claude'],
18
+ when: (answers) => answers.enable_skills,
19
+ validate: (selected) => (selected.length > 0 ? true : 'Selecione ao menos um destino.'),
20
+ },
21
+ ];
@@ -0,0 +1,19 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ export async function setupModule(context, generator) {
6
+ const testsDir = path.join(context.cwd, 'tests');
7
+ await fs.ensureDir(path.join(testsDir, 'e2e', 'helpers'));
8
+
9
+ await generator.copyFile('tests/Pest.php', 'test', 'tests/Pest.php');
10
+ await generator.copyFile('tests/SmokeTest.php', 'test', 'tests/SmokeTest.php');
11
+ await generator.copyFile('tests/e2e/example.spec.js', 'test', 'tests/e2e/example.spec.js');
12
+ await generator.copyFile(
13
+ 'tests/e2e/helpers/loginHelper.js',
14
+ 'test',
15
+ 'tests/e2e/helpers/loginHelper.js'
16
+ );
17
+
18
+ await generator.generateFile('playwright.config.js', context, 'test');
19
+ }
@@ -0,0 +1,8 @@
1
+ export default [
2
+ {
3
+ type: 'confirm',
4
+ name: 'enable_test',
5
+ message: 'Enable testing suite (Pest for PHP + Playwright for E2E)?',
6
+ default: true,
7
+ },
8
+ ];
@@ -0,0 +1,16 @@
1
+ {
2
+ "require-dev": {
3
+ "pestphp/pest": "^4.4"
4
+ },
5
+ "config": {
6
+ "allow-plugins": {
7
+ "pestphp/pest-plugin": true
8
+ }
9
+ },
10
+ "scripts": {
11
+ "test": "pest",
12
+ "test:coverage": "pest --coverage"
13
+ },
14
+ "minimum-stability": "dev",
15
+ "prefer-stable": true
16
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "scripts": {
3
+ "test": "pest",
4
+ "test:e2e": "playwright test",
5
+ "test:e2e:ui": "playwright test --ui",
6
+ "test:e2e:report": "playwright show-report"
7
+ },
8
+ "devDependencies": {
9
+ "@playwright/test": "^1.52.0"
10
+ }
11
+ }
@@ -0,0 +1,29 @@
1
+ import { devices } from '@playwright/test';
2
+
3
+ /**
4
+ * Playwright E2E test configuration.
5
+ * @see https://playwright.dev/docs/test-configuration
6
+ */
7
+ const config = {
8
+ testDir: './tests/e2e',
9
+ timeout: 30 * 1000,
10
+ forbidOnly: !!process.env.CI,
11
+ retries: process.env.CI ? 2 : 0,
12
+ workers: process.env.CI ? 1 : undefined,
13
+ reporter: process.env.CI ? 'github' : 'list',
14
+ use: {
15
+ actionTimeout: 0,
16
+ baseURL: process.env.WP_HOME || 'https://{{projectName}}.lndo.site',
17
+ trace: 'on-first-retry',
18
+ },
19
+ projects: [
20
+ {
21
+ name: 'chromium',
22
+ use: {
23
+ ...devices['Desktop Chrome'],
24
+ },
25
+ },
26
+ ],
27
+ };
28
+
29
+ export default config;
@@ -0,0 +1,39 @@
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ /*
6
+ |--------------------------------------------------------------------------
7
+ | Test Case
8
+ |--------------------------------------------------------------------------
9
+ |
10
+ | The closure you provide to your test functions is always bound to a specific
11
+ | PHPUnit test case class. By default, that class is "PHPUnit\Framework\TestCase".
12
+ | You can change this by specifying a `uses()` call at the top of your file.
13
+ |
14
+ */
15
+
16
+ // uses(Tests\TestCase::class)->in('Feature');
17
+
18
+ /*
19
+ |--------------------------------------------------------------------------
20
+ | Expectations
21
+ |--------------------------------------------------------------------------
22
+ |
23
+ | When you're writing tests, you often need to check that values meet certain
24
+ | conditions. The "expect()" function gives you access to a set of "expectations"
25
+ | methods that you can use to assert different things. Of course, you may use
26
+ | the default PHPUnit assertions at any time as well.
27
+ |
28
+ */
29
+
30
+ /*
31
+ |--------------------------------------------------------------------------
32
+ | Functions
33
+ |--------------------------------------------------------------------------
34
+ |
35
+ | While Pest is very powerful out-of-the-box, you may have some testing
36
+ | helpers that you want to share between tests. Here you can also set
37
+ | up global helper functions that are available in every test file.
38
+ |
39
+ */
@@ -0,0 +1,15 @@
1
+ <?php
2
+
3
+ // phpcs:disable
4
+
5
+ use GuzzleHttp\Client;
6
+
7
+ it('returns a 200 status code on the homepage', function () {
8
+ $client = new Client([
9
+ 'verify' => in_array(env('WP_ENV'), ['production', 'staging']),
10
+ ]);
11
+
12
+ $response = $client->request('GET', env('WP_HOME'));
13
+
14
+ expect($response->getStatusCode())->toBe(200);
15
+ });
@@ -0,0 +1,11 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('homepage returns 200', async ({ page }) => {
4
+ const response = await page.goto('/');
5
+ expect(response?.status()).toBe(200);
6
+ });
7
+
8
+ test('homepage has a title', async ({ page }) => {
9
+ await page.goto('/');
10
+ await expect(page).toHaveTitle(/.+/);
11
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Helper: authenticate an admin user in the WordPress admin panel.
3
+ *
4
+ * @param {import('@playwright/test').Page} page
5
+ * @param {string} [user='admin']
6
+ * @param {string} [pass='admin']
7
+ */
8
+ export async function login(page, user = 'admin', pass = 'admin') {
9
+ await page.goto('/wp/wp-login.php');
10
+ await page.fill('#user_login', user);
11
+ await page.fill('#user_pass', pass);
12
+ await page.click('#wp-submit');
13
+ await page.waitForURL(/wp-admin/);
14
+ }
15
+
16
+ /**
17
+ * Helper: dismiss any WordPress welcome modal that may appear.
18
+ *
19
+ * @param {import('@playwright/test').Page} page
20
+ */
21
+ export async function dismissWelcomeModal(page) {
22
+ try {
23
+ await page.waitForSelector('.components-modal__screen-overlay', { timeout: 3000 });
24
+ const closeButton = page.locator(
25
+ '.components-modal__header button.components-button[aria-label="Close"]'
26
+ );
27
+ if (await closeButton.isVisible()) {
28
+ await closeButton.click();
29
+ await page.waitForSelector('.components-modal__screen-overlay', {
30
+ state: 'detached',
31
+ timeout: 2000,
32
+ });
33
+ } else {
34
+ await page.keyboard.press('Escape');
35
+ await page.waitForTimeout(500);
36
+ }
37
+ } catch {
38
+ // Modal not present or already dismissed — continue.
39
+ }
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codigodoleo/wp-kit",
3
- "version": "3.1.1",
3
+ "version": "3.3.0",
4
4
  "description": "Kit opinativo para padronizar projetos WordPress com CI/CD dinâmico.",
5
5
  "main": "bin/index.js",
6
6
  "bin": {
@@ -0,0 +1,24 @@
1
+ FROM thecodingmachine/php:8.4-v5-fpm-node24
2
+
3
+ # Enable PHP extensions needed for WordPress
4
+ # (mysqli, mysqlnd, redis, zip already enabled by default in the fat image)
5
+ ENV PHP_EXTENSION_BCMATH=1 \
6
+ PHP_EXTENSION_GD=1 \
7
+ PHP_EXTENSION_PDO_MYSQL=1
8
+
9
+ # The base image ends with USER docker — switch to root for installations
10
+ USER root
11
+
12
+ # Install only what is NOT bundled in the base image.
13
+ # Already pre-installed: PHP 8.4, Node 24, npm, yarn (corepack),
14
+ # Composer, mysqli, mysqlnd, redis, zip, curl, git, unzip
15
+ RUN apt-get update \
16
+ && apt-get install -y --no-install-recommends default-mysql-client redis-tools \
17
+ && rm -rf /var/lib/apt/lists/*
18
+
19
+ # WP-CLI (not included in the base image)
20
+ RUN curl -fsSL -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
21
+ && chmod +x /usr/local/bin/wp \
22
+ && wp --info
23
+
24
+ USER docker
@@ -0,0 +1,23 @@
1
+ server {
2
+ listen 80;
3
+ root /workspace/wp;
4
+ index index.php;
5
+
6
+ client_max_body_size 64M;
7
+
8
+ location / {
9
+ try_files $uri $uri/ /index.php$is_args$args;
10
+ }
11
+
12
+ location ~ \.php$ {
13
+ fastcgi_pass app:9000;
14
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
15
+ include fastcgi_params;
16
+ fastcgi_read_timeout 120;
17
+ }
18
+
19
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
20
+ expires max;
21
+ log_not_found off;
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ server {
2
+ listen 80;
3
+ root /workspace/wp;
4
+ index index.php;
5
+
6
+ client_max_body_size 64M;
7
+
8
+ location / {
9
+ try_files $uri $uri/ /index.php$is_args$args;
10
+ }
11
+
12
+ location ~ \.php$ {
13
+ fastcgi_pass app:9000;
14
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
15
+ include fastcgi_params;
16
+ fastcgi_read_timeout 120;
17
+ }
18
+
19
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
20
+ expires max;
21
+ log_not_found off;
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "{{projectName}} Devcontainer",
3
+ "dockerComposeFile": [
4
+ "docker-compose.yml"
5
+ ],
6
+ "service": "app",
7
+ "workspaceFolder": "/workspace",
8
+ "postCreateCommand": "bash .devcontainer/setup.sh",
9
+ "customizations": {
10
+ "vscode": {
11
+ "extensions": [
12
+ "bmewburn.vscode-intelephense-client",
13
+ "esbenp.prettier-vscode",
14
+ "dbaeumer.vscode-eslint",
15
+ "ms-azuretools.vscode-docker"
16
+ ],
17
+ "settings": {
18
+ "editor.formatOnSave": false,
19
+ "terminal.integrated.defaultProfile.linux": "bash"
20
+ }
21
+ }
22
+ },
23
+ "forwardPorts": [
24
+ 8080,
25
+ 3307,
26
+ 6380,
27
+ 5173
28
+ ]
29
+ }
@@ -0,0 +1,73 @@
1
+ services:
2
+ app:
3
+ build:
4
+ context: ..
5
+ dockerfile: .devcontainer/Dockerfile
6
+ container_name: {{projectName}}-app
7
+ working_dir: /workspace
8
+ env_file:
9
+ - ../.env
10
+ volumes:
11
+ - ..:/workspace:cached
12
+ environment:
13
+ WORDPRESS_DB_HOST: db
14
+ WORDPRESS_DB_USER: wordpress
15
+ WORDPRESS_DB_PASSWORD: wordpress
16
+ WORDPRESS_DB_NAME: wordpress
17
+ depends_on:
18
+ db:
19
+ condition: service_healthy
20
+ redis:
21
+ condition: service_started
22
+ networks:
23
+ - wp
24
+
25
+ web:
26
+ image: nginx:alpine
27
+ container_name: {{projectName}}-web
28
+ ports:
29
+ - "8080:80"
30
+ - "5173:5173"
31
+ volumes:
32
+ - ..:/workspace:ro
33
+ - ./.devcontainer/config/nginx.conf:/etc/nginx/conf.d/default.conf:ro
34
+ depends_on:
35
+ - app
36
+ networks:
37
+ - wp
38
+
39
+ db:
40
+ image: mariadb:11
41
+ container_name: {{projectName}}-db
42
+ restart: unless-stopped
43
+ environment:
44
+ MYSQL_DATABASE: wordpress
45
+ MYSQL_USER: wordpress
46
+ MYSQL_PASSWORD: wordpress
47
+ MYSQL_ROOT_PASSWORD: root
48
+ ports:
49
+ - "3307:3306"
50
+ volumes:
51
+ - db-data:/var/lib/mysql
52
+ networks:
53
+ - wp
54
+ healthcheck:
55
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
56
+ timeout: 20s
57
+ retries: 10
58
+
59
+ redis:
60
+ image: redis:7-alpine
61
+ container_name: {{projectName}}-redis
62
+ restart: unless-stopped
63
+ ports:
64
+ - "6380:6379"
65
+ networks:
66
+ - wp
67
+
68
+ networks:
69
+ wp:
70
+ driver: bridge
71
+
72
+ volumes:
73
+ db-data:
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # Devcontainer post-create setup — runs once after the container is created.
3
+ # Delegates to unified scripts so Lando, CI/CD and devcontainer share the same logic.
4
+ set -euo pipefail
5
+
6
+ git config --global --add safe.directory /workspace || true
7
+
8
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.."; pwd)"
9
+
10
+ bash "${PROJECT_ROOT}/server/cmd/setup-php.sh"
11
+ bash "${PROJECT_ROOT}/server/cmd/setup-node.sh"
12
+
13
+ if command -v wp >/dev/null 2>&1; then
14
+ bash "${PROJECT_ROOT}/server/cmd/install-wp.sh"
15
+ fi
16
+
17
+ echo "Devcontainer setup completed."
@@ -1,27 +1,50 @@
1
- PROJECT_NAME="{{projectName}}" PROJECT_VERSION="{{projectVersion}}" PROJECT_DOMAIN="{{projectDomain}}"
2
- APP_URL="https://{{projectDomain}}" AUTHOR="{{author}}" PHP_VERSION="{{phpVersion}}" NODE_VERSION="{{nodeVersion}}"
3
- WP_CORE_VERSION="{{wpCoreVersion}}"{{#if enable_sage}}
4
- SAGE_VERSION="{{sageVersion}}"{{/if}}
5
- GIT_REPOSITORY="{{gitRepository}}" WORDPRESS_SITE_URL="https://{{projectDomain}}"
6
- WORDPRESS_DB_NAME="wordpress" WORDPRESS_DB_USER="wordpress" WORDPRESS_DB_PASSWORD="wordpress"
7
- WORDPRESS_DB_HOST="database" WORDPRESS_DB_CHARSET="utf8" WORDPRESS_DB_COLLATE=""
8
- WORDPRESS_TABLE_PREFIX="wp_" WORDPRESS_DEBUG={{enableDebug}}
1
+ PROJECT_NAME="{{projectName}}"
2
+ PROJECT_VERSION="{{projectVersion}}"
3
+ PROJECT_DOMAIN="{{projectDomain}}"
4
+ APP_URL="https://{{projectDomain}}"
5
+ AUTHOR="{{author}}"
6
+ PHP_VERSION="{{phpVersion}}"
7
+ NODE_VERSION="{{nodeVersion}}"
8
+ WP_CORE_VERSION="{{wpCoreVersion}}"
9
+ {{#if enable_sage}}
10
+ SAGE_VERSION="{{sageVersion}}"
11
+ {{/if}}
12
+ GIT_REPOSITORY="{{gitRepository}}"
13
+
14
+ WORDPRESS_SITE_URL="https://{{projectDomain}}"
15
+ WORDPRESS_DB_NAME="wordpress"
16
+ WORDPRESS_DB_USER="wordpress"
17
+ WORDPRESS_DB_PASSWORD="wordpress"
18
+ WORDPRESS_DB_HOST="database"
19
+ WORDPRESS_DB_CHARSET="utf8"
20
+ WORDPRESS_DB_COLLATE=""
21
+ WORDPRESS_TABLE_PREFIX="wp_"
22
+ WORDPRESS_DEBUG={{enableDebug}}
9
23
  WORDPRESS_DEBUG_DISPLAY={{enableDebug}}
10
24
  WORDPRESS_DEBUG_LOG={{enableDebug}}
11
25
  WORDPRESS_SCRIPT_DEBUG={{enableDebug}}
12
- WORDPRESS_DISABLE_UPDATE=true WORDPRESS_DISABLE_CRON=true WORDPRESS_AUTOSAVE_INTERVAL="600"
13
- WORDPRESS_POST_REVISIONS="2" WORDPRESS_WP_ENVIRONMENT_TYPE="local" WORDPRESS_DISALLOW_FILE_MODS=true
14
- WORDPRESS_FORCE_SSL_ADMIN=true WORDPRESS_AUTOMATIC_UPDATER_DISABLED=true
15
- WORDPRESS_WP_AUTO_UPDATE_CORE=false ### Redis ###
26
+ WORDPRESS_DISABLE_UPDATE=true
27
+ WORDPRESS_DISABLE_CRON=true
28
+ WORDPRESS_AUTOSAVE_INTERVAL="600"
29
+ WORDPRESS_POST_REVISIONS="2"
30
+ WORDPRESS_WP_ENVIRONMENT_TYPE="local"
31
+ WORDPRESS_DISALLOW_FILE_MODS=true
32
+ WORDPRESS_FORCE_SSL_ADMIN=true
33
+ WORDPRESS_AUTOMATIC_UPDATER_DISABLED=true
34
+ WORDPRESS_WP_AUTO_UPDATE_CORE=false
35
+
36
+ ### Redis ###
16
37
  {{#if enable_redis}}
17
- WORDPRESS_REDIS_HOST=redis WORDPRESS_REDIS_PORT=6379
38
+ WORDPRESS_REDIS_HOST=redis
39
+ WORDPRESS_REDIS_PORT=6379
18
40
  {{/if}}
19
41
 
20
- ### WordPress salts ### WORDPRESS_AUTH_KEY={{{salts.AUTH_KEY}}}
42
+ ### WordPress salts ###
43
+ WORDPRESS_AUTH_KEY={{{salts.AUTH_KEY}}}
21
44
  WORDPRESS_SECURE_AUTH_KEY={{{salts.SECURE_AUTH_KEY}}}
22
45
  WORDPRESS_LOGGED_IN_KEY={{{salts.LOGGED_IN_KEY}}}
23
46
  WORDPRESS_NONCE_KEY={{{salts.NONCE_KEY}}}
24
47
  WORDPRESS_AUTH_SALT={{{salts.AUTH_SALT}}}
25
48
  WORDPRESS_SECURE_AUTH_SALT={{{salts.SECURE_AUTH_SALT}}}
26
49
  WORDPRESS_LOGGED_IN_SALT={{{salts.LOGGED_IN_SALT}}}
27
- WORDPRESS_NONCE_SALT={{{salts.NONCE_SALT}}}
50
+ WORDPRESS_NONCE_SALT={{{salts.NONCE_SALT}}}