@dword-design/base-config-app 8.0.2 → 9.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.
- package/dist/index.js +39 -13
- package/dist/playbook.yml +86 -0
- package/dist/requirements.yml +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { defineBaseConfig } from "@dword-design/base";
|
|
2
3
|
import getBaseConfigNuxt, { getEslintConfig } from "@dword-design/base-config-nuxt";
|
|
3
4
|
import packageName from "depcheck-package-name";
|
|
5
|
+
import endent from "endent";
|
|
4
6
|
import { execaCommand } from "execa";
|
|
7
|
+
import fs from "fs-extra";
|
|
5
8
|
import outputFiles from "output-files";
|
|
6
9
|
import { readPackageSync } from "read-pkg";
|
|
7
10
|
import yaml from "yaml";
|
|
8
11
|
import dockerCompose from "./docker-compose.js";
|
|
9
12
|
import getEcosystemConfig from "./get-ecosystem-config.js";
|
|
10
13
|
import getNginxConfig from "./get-nginx-config.js";
|
|
14
|
+
const resolver = createRequire(import.meta.url);
|
|
15
|
+
const requirementsYml = fs.readFileSync(resolver.resolve("./requirements.yml"), "utf8");
|
|
16
|
+
const playbookYml = fs.readFileSync(resolver.resolve("./playbook.yml"), "utf8");
|
|
11
17
|
export default defineBaseConfig(function (config) {
|
|
12
18
|
const packageConfig = readPackageSync({
|
|
13
19
|
cwd: this.cwd
|
|
@@ -31,33 +37,53 @@ export default defineBaseConfig(function (config) {
|
|
|
31
37
|
"ecosystem.json": JSON.stringify(getEcosystemConfig(packageConfig, {
|
|
32
38
|
cwd: this.cwd
|
|
33
39
|
}), void 0, 2),
|
|
34
|
-
"nginx/default.config": getNginxConfig(packageConfig)
|
|
40
|
+
"nginx/default.config": getNginxConfig(packageConfig),
|
|
41
|
+
"playbook.yml": playbookYml,
|
|
42
|
+
"requirements.yml": requirementsYml
|
|
35
43
|
});
|
|
36
44
|
},
|
|
37
45
|
renovateConfig: {
|
|
38
46
|
ignorePaths: ["docker-compose.yml"]
|
|
39
47
|
},
|
|
40
48
|
...(!packageConfig.private && {
|
|
41
|
-
deployPlugins: [[packageName`@semantic-release/exec`,
|
|
42
|
-
|
|
43
|
-
* TODO: For some reason there are unpushed changes in CI before this command, which is why
|
|
44
|
-
* we need --force. The package.json version change and the changelog change should be
|
|
45
|
-
* pushed by @semantic-release/git in prepare phase.
|
|
46
|
-
* Interestingly I also get "Updates were rejected because the remote contains work that you do
|
|
47
|
-
* not have locally." when pulling, so something seems to get pushed.
|
|
48
|
-
* Output the unpushed diff commit: Add this in publishCmd here below before the deploy command:
|
|
49
|
-
* git log -p @{upstream}.. --max-count=1 &&
|
|
50
|
-
*/
|
|
51
|
-
{
|
|
52
|
-
publishCmd: `${packageName`pm2`} deploy production --force`
|
|
49
|
+
deployPlugins: [[packageName`@semantic-release/exec`, {
|
|
50
|
+
publishCmd: "ansible-playbook playbook.yml -i .inventory"
|
|
53
51
|
}]],
|
|
54
52
|
preDeploySteps: [{
|
|
53
|
+
name: "Build project",
|
|
54
|
+
run: "pnpm build"
|
|
55
|
+
}, {
|
|
56
|
+
name: "Create deploy artifact",
|
|
57
|
+
run: "tar -czf deploy.tgz .output"
|
|
58
|
+
}, {
|
|
59
|
+
name: "Install Python",
|
|
60
|
+
uses: "actions/setup-python@v4",
|
|
61
|
+
with: {
|
|
62
|
+
"python-version": "3.x"
|
|
63
|
+
}
|
|
64
|
+
}, {
|
|
65
|
+
name: "Install ansible",
|
|
66
|
+
run: endent`
|
|
67
|
+
python -m pip install --upgrade pip
|
|
68
|
+
pip install ansible
|
|
69
|
+
`
|
|
70
|
+
}, {
|
|
71
|
+
name: "Install requirements",
|
|
72
|
+
run: "ansible-galaxy install -r requirements.yml"
|
|
73
|
+
}, {
|
|
55
74
|
uses: "webfactory/ssh-agent@v0.5.1",
|
|
56
75
|
with: {
|
|
57
76
|
"ssh-private-key": "${{ secrets.SSH_PRIVATE_KEY }}"
|
|
58
77
|
}
|
|
59
78
|
}, {
|
|
60
79
|
run: "ssh-keyscan -H sebastianlandwehr.com >> ~/.ssh/known_hosts"
|
|
80
|
+
}, {
|
|
81
|
+
run: endent`
|
|
82
|
+
cat <<EOF > .inventory
|
|
83
|
+
[servers]
|
|
84
|
+
sebastianlandwehr.com ansible_user=\${{ secrets.SSH_USER }} ansible_become=True
|
|
85
|
+
EOF
|
|
86
|
+
`
|
|
61
87
|
}]
|
|
62
88
|
}),
|
|
63
89
|
commands: {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
- name: Deploy app with deploy_helper (artifact + auto-link shared)
|
|
3
|
+
hosts: app
|
|
4
|
+
become: true
|
|
5
|
+
|
|
6
|
+
vars:
|
|
7
|
+
# Base paths
|
|
8
|
+
app_name: >-
|
|
9
|
+
{{
|
|
10
|
+
(lookup('file', 'package.json') | from_json).name
|
|
11
|
+
| regex_replace('^.*/', '')
|
|
12
|
+
}}
|
|
13
|
+
deploy_to: "/var/www/{{ app_name }}"
|
|
14
|
+
|
|
15
|
+
# Local artifact built by GitHub Actions (tar.gz)
|
|
16
|
+
artifact_local_path: ./deploy.tgz
|
|
17
|
+
|
|
18
|
+
tasks:
|
|
19
|
+
- name: Prepare deploy folder layout and compute new release path
|
|
20
|
+
community.general.deploy_helper:
|
|
21
|
+
path: "{{ deploy_to }}"
|
|
22
|
+
release: "{{ release_id | default(ansible_date_time.iso8601_basic_short) }}"
|
|
23
|
+
state: present
|
|
24
|
+
register: dh
|
|
25
|
+
|
|
26
|
+
- name: Upload artifact to server
|
|
27
|
+
ansible.builtin.copy:
|
|
28
|
+
src: "{{ artifact_local_path }}"
|
|
29
|
+
dest: "/tmp/{{ app_name }}-{{ dh.release }}.tgz"
|
|
30
|
+
mode: "0644"
|
|
31
|
+
|
|
32
|
+
- name: Ensure new release directory exists
|
|
33
|
+
ansible.builtin.file:
|
|
34
|
+
path: "{{ dh.new_release_path }}"
|
|
35
|
+
state: directory
|
|
36
|
+
mode: "0755"
|
|
37
|
+
|
|
38
|
+
- name: Extract artifact into new release path
|
|
39
|
+
ansible.builtin.unarchive:
|
|
40
|
+
src: "/tmp/{{ app_name }}-{{ dh.release }}.tgz"
|
|
41
|
+
dest: "{{ dh.new_release_path }}"
|
|
42
|
+
remote_src: true
|
|
43
|
+
|
|
44
|
+
# --- AUTO-LINK: link all direct children of shared/ into the release root ---
|
|
45
|
+
- name: Ensure shared directory exists
|
|
46
|
+
ansible.builtin.file:
|
|
47
|
+
path: "{{ deploy_to }}/shared"
|
|
48
|
+
state: directory
|
|
49
|
+
mode: "0755"
|
|
50
|
+
|
|
51
|
+
- name: List all items in shared/ (including dotfiles)
|
|
52
|
+
ansible.builtin.find:
|
|
53
|
+
paths: "{{ deploy_to }}/shared"
|
|
54
|
+
file_type: any
|
|
55
|
+
hidden: true
|
|
56
|
+
recurse: false
|
|
57
|
+
register: shared_items
|
|
58
|
+
|
|
59
|
+
- name: Symlink all shared items into the new release (same name)
|
|
60
|
+
ansible.builtin.file:
|
|
61
|
+
src: "{{ item.path }}"
|
|
62
|
+
dest: "{{ dh.new_release_path }}/{{ item.path | basename }}"
|
|
63
|
+
state: link
|
|
64
|
+
force: true
|
|
65
|
+
loop: "{{ shared_items.files }}"
|
|
66
|
+
|
|
67
|
+
# Optional server-side steps go here (migrations, perms, etc.)
|
|
68
|
+
# - name: Run migrations
|
|
69
|
+
# ansible.builtin.command: "{{ dh.new_release_path }}/bin/migrate"
|
|
70
|
+
# changed_when: true
|
|
71
|
+
|
|
72
|
+
- name: Finalize: switch current -> new release (atomic)
|
|
73
|
+
community.general.deploy_helper:
|
|
74
|
+
path: "{{ deploy_to }}"
|
|
75
|
+
release: "{{ dh.release }}"
|
|
76
|
+
state: finalize
|
|
77
|
+
|
|
78
|
+
- name: Restart app
|
|
79
|
+
ansible.builtin.command: "pm2 startOrReload ecosystem.json"
|
|
80
|
+
changed_when: true
|
|
81
|
+
|
|
82
|
+
- name: Cleanup old releases
|
|
83
|
+
community.general.deploy_helper:
|
|
84
|
+
path: "{{ deploy_to }}"
|
|
85
|
+
keep_releases: 5
|
|
86
|
+
state: cleanup
|