@orange-soft/strapi-deployment-trigger 1.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/README.md +116 -0
- package/admin/jsconfig.json +10 -0
- package/admin/src/components/Initializer.jsx +18 -0
- package/admin/src/components/PluginIcon.jsx +5 -0
- package/admin/src/index.js +49 -0
- package/admin/src/pages/App.jsx +17 -0
- package/admin/src/pages/HomePage.jsx +241 -0
- package/admin/src/pages/SettingsPage.jsx +370 -0
- package/admin/src/pluginId.js +1 -0
- package/admin/src/translations/en.json +3 -0
- package/admin/src/utils/getTranslation.js +5 -0
- package/dist/_chunks/App-3JntxPYv.js +520 -0
- package/dist/_chunks/App-C0Byi5W1.mjs +520 -0
- package/dist/_chunks/en-BDvOU5UD.js +6 -0
- package/dist/_chunks/en-DdBZuj6F.mjs +6 -0
- package/dist/_chunks/index-C18aSW5z.mjs +70 -0
- package/dist/_chunks/index-CqpMwL_C.js +69 -0
- package/dist/admin/index.js +3 -0
- package/dist/admin/index.mjs +4 -0
- package/dist/server/index.js +264 -0
- package/dist/server/index.mjs +265 -0
- package/package.json +84 -0
- package/server/jsconfig.json +10 -0
- package/server/src/bootstrap.js +5 -0
- package/server/src/config/index.js +4 -0
- package/server/src/content-types/index.js +1 -0
- package/server/src/controllers/controller.js +95 -0
- package/server/src/controllers/index.js +5 -0
- package/server/src/destroy.js +5 -0
- package/server/src/index.js +31 -0
- package/server/src/middlewares/index.js +1 -0
- package/server/src/policies/index.js +1 -0
- package/server/src/register.js +5 -0
- package/server/src/routes/admin/index.js +37 -0
- package/server/src/routes/content-api/index.js +14 -0
- package/server/src/routes/index.js +9 -0
- package/server/src/services/index.js +5 -0
- package/server/src/services/service.js +124 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const bootstrap = ({ strapi }) => {
|
|
3
|
+
};
|
|
4
|
+
const destroy = ({ strapi }) => {
|
|
5
|
+
};
|
|
6
|
+
const register = ({ strapi }) => {
|
|
7
|
+
};
|
|
8
|
+
const config = {
|
|
9
|
+
default: {},
|
|
10
|
+
validator() {
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const contentTypes = {};
|
|
14
|
+
const PLUGIN_ID$1 = "deployment-trigger";
|
|
15
|
+
const getService = (strapi) => strapi.plugin(PLUGIN_ID$1).service("service");
|
|
16
|
+
const controller = ({ strapi }) => ({
|
|
17
|
+
index(ctx) {
|
|
18
|
+
ctx.body = getService(strapi).getWelcomeMessage();
|
|
19
|
+
},
|
|
20
|
+
async getSettings(ctx) {
|
|
21
|
+
const settings = await getService(strapi).getSettings();
|
|
22
|
+
ctx.body = { data: settings };
|
|
23
|
+
},
|
|
24
|
+
async saveSettings(ctx) {
|
|
25
|
+
const { data } = ctx.request.body;
|
|
26
|
+
const settings = await getService(strapi).saveSettings(data);
|
|
27
|
+
ctx.body = { data: settings };
|
|
28
|
+
},
|
|
29
|
+
async getStatus(ctx) {
|
|
30
|
+
const service2 = getService(strapi);
|
|
31
|
+
const settings = await service2.getSettings();
|
|
32
|
+
const configured = await service2.isConfigured();
|
|
33
|
+
const hasToken = await service2.hasToken();
|
|
34
|
+
const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
|
|
35
|
+
ctx.body = {
|
|
36
|
+
data: {
|
|
37
|
+
configured,
|
|
38
|
+
hasToken,
|
|
39
|
+
settings,
|
|
40
|
+
parsed: { owner, repo }
|
|
41
|
+
// Include parsed values for display
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
async trigger(ctx) {
|
|
46
|
+
const service2 = getService(strapi);
|
|
47
|
+
const githubToken = await service2.getToken();
|
|
48
|
+
if (!githubToken) {
|
|
49
|
+
return ctx.badRequest("GitHub token is not configured. Please add it in Settings.");
|
|
50
|
+
}
|
|
51
|
+
const settings = await service2.getSettings();
|
|
52
|
+
const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
|
|
53
|
+
if (!owner || !repo) {
|
|
54
|
+
return ctx.badRequest("GitHub repository URL is not configured or invalid. Please configure it in Settings.");
|
|
55
|
+
}
|
|
56
|
+
const { workflow = settings.workflow, branch = settings.branch } = ctx.request.body || {};
|
|
57
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
Accept: "application/vnd.github.v3+json",
|
|
63
|
+
Authorization: `Bearer ${githubToken}`,
|
|
64
|
+
"Content-Type": "application/json"
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({ ref: branch })
|
|
67
|
+
});
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
const errorText = await response.text();
|
|
70
|
+
strapi.log.error(`GitHub API error: ${response.status} - ${errorText}`);
|
|
71
|
+
return ctx.badRequest(`GitHub API error: ${response.status} - ${errorText}`);
|
|
72
|
+
}
|
|
73
|
+
strapi.log.info(`Deployment triggered for ${owner}/${repo} on branch ${branch}`);
|
|
74
|
+
const actionsUrl = `https://github.com/${owner}/${repo}/actions`;
|
|
75
|
+
ctx.body = {
|
|
76
|
+
data: {
|
|
77
|
+
success: true,
|
|
78
|
+
message: `Deployment triggered successfully for ${owner}/${repo}`,
|
|
79
|
+
repository: `${owner}/${repo}`,
|
|
80
|
+
workflow,
|
|
81
|
+
branch,
|
|
82
|
+
actionsUrl
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
strapi.log.error("Error triggering deployment:", error);
|
|
87
|
+
return ctx.badRequest(`Failed to trigger deployment: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const controllers = {
|
|
92
|
+
controller
|
|
93
|
+
};
|
|
94
|
+
const middlewares = {};
|
|
95
|
+
const policies = {};
|
|
96
|
+
const contentAPIRoutes = () => ({
|
|
97
|
+
type: "content-api",
|
|
98
|
+
routes: [
|
|
99
|
+
{
|
|
100
|
+
method: "GET",
|
|
101
|
+
path: "/",
|
|
102
|
+
// name of the controller file & the method.
|
|
103
|
+
handler: "controller.index",
|
|
104
|
+
config: {
|
|
105
|
+
policies: []
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
const adminAPIRoutes = () => ({
|
|
111
|
+
type: "admin",
|
|
112
|
+
routes: [
|
|
113
|
+
{
|
|
114
|
+
method: "GET",
|
|
115
|
+
path: "/settings",
|
|
116
|
+
handler: "controller.getSettings",
|
|
117
|
+
config: {
|
|
118
|
+
policies: []
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
method: "PUT",
|
|
123
|
+
path: "/settings",
|
|
124
|
+
handler: "controller.saveSettings",
|
|
125
|
+
config: {
|
|
126
|
+
policies: []
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
method: "GET",
|
|
131
|
+
path: "/status",
|
|
132
|
+
handler: "controller.getStatus",
|
|
133
|
+
config: {
|
|
134
|
+
policies: []
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
method: "POST",
|
|
139
|
+
path: "/trigger",
|
|
140
|
+
handler: "controller.trigger",
|
|
141
|
+
config: {
|
|
142
|
+
policies: []
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
});
|
|
147
|
+
const routes = {
|
|
148
|
+
"content-api": contentAPIRoutes,
|
|
149
|
+
admin: adminAPIRoutes
|
|
150
|
+
};
|
|
151
|
+
const PLUGIN_ID = "deployment-trigger";
|
|
152
|
+
const STORE_KEY = "settings";
|
|
153
|
+
const DEFAULT_SETTINGS = {
|
|
154
|
+
repoUrl: "",
|
|
155
|
+
workflow: "deploy.yml",
|
|
156
|
+
branch: "master"
|
|
157
|
+
};
|
|
158
|
+
const service = ({ strapi }) => ({
|
|
159
|
+
getWelcomeMessage() {
|
|
160
|
+
return "Welcome to Strapi Deployment Trigger";
|
|
161
|
+
},
|
|
162
|
+
maskToken(token) {
|
|
163
|
+
if (!token || token.length < 20) return null;
|
|
164
|
+
const head = token.slice(0, 15);
|
|
165
|
+
const tail = token.slice(-4);
|
|
166
|
+
return `${head}...${tail}`;
|
|
167
|
+
},
|
|
168
|
+
parseRepoUrl(repoUrl) {
|
|
169
|
+
if (!repoUrl) return { owner: null, repo: null };
|
|
170
|
+
try {
|
|
171
|
+
const url = new URL(repoUrl);
|
|
172
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
173
|
+
if (parts.length >= 2) {
|
|
174
|
+
return { owner: parts[0], repo: parts[1] };
|
|
175
|
+
}
|
|
176
|
+
} catch (e) {
|
|
177
|
+
}
|
|
178
|
+
return { owner: null, repo: null };
|
|
179
|
+
},
|
|
180
|
+
async getSettings() {
|
|
181
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
182
|
+
const dbSettings = await store.get({ key: STORE_KEY });
|
|
183
|
+
const envToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
|
|
184
|
+
if (dbSettings && dbSettings.repoUrl) {
|
|
185
|
+
const token2 = dbSettings.githubToken || envToken;
|
|
186
|
+
return {
|
|
187
|
+
...dbSettings,
|
|
188
|
+
githubToken: void 0,
|
|
189
|
+
// Never expose full token
|
|
190
|
+
hasToken: !!token2,
|
|
191
|
+
maskedToken: this.maskToken(token2)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const pluginConfig = strapi.config.get(`plugin::${PLUGIN_ID}`) || {};
|
|
195
|
+
if (pluginConfig.githubOwner && pluginConfig.githubRepo) {
|
|
196
|
+
return {
|
|
197
|
+
repoUrl: `https://github.com/${pluginConfig.githubOwner}/${pluginConfig.githubRepo}`,
|
|
198
|
+
workflow: pluginConfig.workflow || DEFAULT_SETTINGS.workflow,
|
|
199
|
+
branch: pluginConfig.branch || DEFAULT_SETTINGS.branch,
|
|
200
|
+
hasToken: !!envToken,
|
|
201
|
+
maskedToken: this.maskToken(envToken)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const token = dbSettings?.githubToken || envToken;
|
|
205
|
+
return {
|
|
206
|
+
...DEFAULT_SETTINGS,
|
|
207
|
+
...dbSettings,
|
|
208
|
+
githubToken: void 0,
|
|
209
|
+
hasToken: !!token,
|
|
210
|
+
maskedToken: this.maskToken(token)
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
async saveSettings(settings) {
|
|
214
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
215
|
+
const existingSettings = await store.get({ key: STORE_KEY }) || {};
|
|
216
|
+
const settingsToSave = {
|
|
217
|
+
repoUrl: settings.repoUrl,
|
|
218
|
+
workflow: settings.workflow || DEFAULT_SETTINGS.workflow,
|
|
219
|
+
branch: settings.branch || DEFAULT_SETTINGS.branch,
|
|
220
|
+
// Only update token if a new one is provided
|
|
221
|
+
githubToken: settings.githubToken || existingSettings.githubToken
|
|
222
|
+
};
|
|
223
|
+
await store.set({ key: STORE_KEY, value: settingsToSave });
|
|
224
|
+
return {
|
|
225
|
+
...settingsToSave,
|
|
226
|
+
githubToken: void 0,
|
|
227
|
+
hasToken: !!settingsToSave.githubToken || !!process.env.GITHUB_PERSONAL_ACCESS_TOKEN
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
async getToken() {
|
|
231
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
232
|
+
const dbSettings = await store.get({ key: STORE_KEY });
|
|
233
|
+
if (dbSettings?.githubToken) {
|
|
234
|
+
return dbSettings.githubToken;
|
|
235
|
+
}
|
|
236
|
+
return process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
|
|
237
|
+
},
|
|
238
|
+
async isConfigured() {
|
|
239
|
+
const settings = await this.getSettings();
|
|
240
|
+
const hasToken = await this.getToken();
|
|
241
|
+
const { owner, repo } = this.parseRepoUrl(settings.repoUrl);
|
|
242
|
+
return !!(owner && repo && hasToken);
|
|
243
|
+
},
|
|
244
|
+
async hasToken() {
|
|
245
|
+
const token = await this.getToken();
|
|
246
|
+
return !!token;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
const services = {
|
|
250
|
+
service
|
|
251
|
+
};
|
|
252
|
+
const index = {
|
|
253
|
+
bootstrap,
|
|
254
|
+
destroy,
|
|
255
|
+
register,
|
|
256
|
+
config,
|
|
257
|
+
controllers,
|
|
258
|
+
contentTypes,
|
|
259
|
+
middlewares,
|
|
260
|
+
policies,
|
|
261
|
+
routes,
|
|
262
|
+
services
|
|
263
|
+
};
|
|
264
|
+
module.exports = index;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
const bootstrap = ({ strapi }) => {
|
|
2
|
+
};
|
|
3
|
+
const destroy = ({ strapi }) => {
|
|
4
|
+
};
|
|
5
|
+
const register = ({ strapi }) => {
|
|
6
|
+
};
|
|
7
|
+
const config = {
|
|
8
|
+
default: {},
|
|
9
|
+
validator() {
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const contentTypes = {};
|
|
13
|
+
const PLUGIN_ID$1 = "deployment-trigger";
|
|
14
|
+
const getService = (strapi) => strapi.plugin(PLUGIN_ID$1).service("service");
|
|
15
|
+
const controller = ({ strapi }) => ({
|
|
16
|
+
index(ctx) {
|
|
17
|
+
ctx.body = getService(strapi).getWelcomeMessage();
|
|
18
|
+
},
|
|
19
|
+
async getSettings(ctx) {
|
|
20
|
+
const settings = await getService(strapi).getSettings();
|
|
21
|
+
ctx.body = { data: settings };
|
|
22
|
+
},
|
|
23
|
+
async saveSettings(ctx) {
|
|
24
|
+
const { data } = ctx.request.body;
|
|
25
|
+
const settings = await getService(strapi).saveSettings(data);
|
|
26
|
+
ctx.body = { data: settings };
|
|
27
|
+
},
|
|
28
|
+
async getStatus(ctx) {
|
|
29
|
+
const service2 = getService(strapi);
|
|
30
|
+
const settings = await service2.getSettings();
|
|
31
|
+
const configured = await service2.isConfigured();
|
|
32
|
+
const hasToken = await service2.hasToken();
|
|
33
|
+
const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
|
|
34
|
+
ctx.body = {
|
|
35
|
+
data: {
|
|
36
|
+
configured,
|
|
37
|
+
hasToken,
|
|
38
|
+
settings,
|
|
39
|
+
parsed: { owner, repo }
|
|
40
|
+
// Include parsed values for display
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
async trigger(ctx) {
|
|
45
|
+
const service2 = getService(strapi);
|
|
46
|
+
const githubToken = await service2.getToken();
|
|
47
|
+
if (!githubToken) {
|
|
48
|
+
return ctx.badRequest("GitHub token is not configured. Please add it in Settings.");
|
|
49
|
+
}
|
|
50
|
+
const settings = await service2.getSettings();
|
|
51
|
+
const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
|
|
52
|
+
if (!owner || !repo) {
|
|
53
|
+
return ctx.badRequest("GitHub repository URL is not configured or invalid. Please configure it in Settings.");
|
|
54
|
+
}
|
|
55
|
+
const { workflow = settings.workflow, branch = settings.branch } = ctx.request.body || {};
|
|
56
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
Accept: "application/vnd.github.v3+json",
|
|
62
|
+
Authorization: `Bearer ${githubToken}`,
|
|
63
|
+
"Content-Type": "application/json"
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify({ ref: branch })
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
const errorText = await response.text();
|
|
69
|
+
strapi.log.error(`GitHub API error: ${response.status} - ${errorText}`);
|
|
70
|
+
return ctx.badRequest(`GitHub API error: ${response.status} - ${errorText}`);
|
|
71
|
+
}
|
|
72
|
+
strapi.log.info(`Deployment triggered for ${owner}/${repo} on branch ${branch}`);
|
|
73
|
+
const actionsUrl = `https://github.com/${owner}/${repo}/actions`;
|
|
74
|
+
ctx.body = {
|
|
75
|
+
data: {
|
|
76
|
+
success: true,
|
|
77
|
+
message: `Deployment triggered successfully for ${owner}/${repo}`,
|
|
78
|
+
repository: `${owner}/${repo}`,
|
|
79
|
+
workflow,
|
|
80
|
+
branch,
|
|
81
|
+
actionsUrl
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
} catch (error) {
|
|
85
|
+
strapi.log.error("Error triggering deployment:", error);
|
|
86
|
+
return ctx.badRequest(`Failed to trigger deployment: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const controllers = {
|
|
91
|
+
controller
|
|
92
|
+
};
|
|
93
|
+
const middlewares = {};
|
|
94
|
+
const policies = {};
|
|
95
|
+
const contentAPIRoutes = () => ({
|
|
96
|
+
type: "content-api",
|
|
97
|
+
routes: [
|
|
98
|
+
{
|
|
99
|
+
method: "GET",
|
|
100
|
+
path: "/",
|
|
101
|
+
// name of the controller file & the method.
|
|
102
|
+
handler: "controller.index",
|
|
103
|
+
config: {
|
|
104
|
+
policies: []
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
});
|
|
109
|
+
const adminAPIRoutes = () => ({
|
|
110
|
+
type: "admin",
|
|
111
|
+
routes: [
|
|
112
|
+
{
|
|
113
|
+
method: "GET",
|
|
114
|
+
path: "/settings",
|
|
115
|
+
handler: "controller.getSettings",
|
|
116
|
+
config: {
|
|
117
|
+
policies: []
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
method: "PUT",
|
|
122
|
+
path: "/settings",
|
|
123
|
+
handler: "controller.saveSettings",
|
|
124
|
+
config: {
|
|
125
|
+
policies: []
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
method: "GET",
|
|
130
|
+
path: "/status",
|
|
131
|
+
handler: "controller.getStatus",
|
|
132
|
+
config: {
|
|
133
|
+
policies: []
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
method: "POST",
|
|
138
|
+
path: "/trigger",
|
|
139
|
+
handler: "controller.trigger",
|
|
140
|
+
config: {
|
|
141
|
+
policies: []
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
});
|
|
146
|
+
const routes = {
|
|
147
|
+
"content-api": contentAPIRoutes,
|
|
148
|
+
admin: adminAPIRoutes
|
|
149
|
+
};
|
|
150
|
+
const PLUGIN_ID = "deployment-trigger";
|
|
151
|
+
const STORE_KEY = "settings";
|
|
152
|
+
const DEFAULT_SETTINGS = {
|
|
153
|
+
repoUrl: "",
|
|
154
|
+
workflow: "deploy.yml",
|
|
155
|
+
branch: "master"
|
|
156
|
+
};
|
|
157
|
+
const service = ({ strapi }) => ({
|
|
158
|
+
getWelcomeMessage() {
|
|
159
|
+
return "Welcome to Strapi Deployment Trigger";
|
|
160
|
+
},
|
|
161
|
+
maskToken(token) {
|
|
162
|
+
if (!token || token.length < 20) return null;
|
|
163
|
+
const head = token.slice(0, 15);
|
|
164
|
+
const tail = token.slice(-4);
|
|
165
|
+
return `${head}...${tail}`;
|
|
166
|
+
},
|
|
167
|
+
parseRepoUrl(repoUrl) {
|
|
168
|
+
if (!repoUrl) return { owner: null, repo: null };
|
|
169
|
+
try {
|
|
170
|
+
const url = new URL(repoUrl);
|
|
171
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
172
|
+
if (parts.length >= 2) {
|
|
173
|
+
return { owner: parts[0], repo: parts[1] };
|
|
174
|
+
}
|
|
175
|
+
} catch (e) {
|
|
176
|
+
}
|
|
177
|
+
return { owner: null, repo: null };
|
|
178
|
+
},
|
|
179
|
+
async getSettings() {
|
|
180
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
181
|
+
const dbSettings = await store.get({ key: STORE_KEY });
|
|
182
|
+
const envToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
|
|
183
|
+
if (dbSettings && dbSettings.repoUrl) {
|
|
184
|
+
const token2 = dbSettings.githubToken || envToken;
|
|
185
|
+
return {
|
|
186
|
+
...dbSettings,
|
|
187
|
+
githubToken: void 0,
|
|
188
|
+
// Never expose full token
|
|
189
|
+
hasToken: !!token2,
|
|
190
|
+
maskedToken: this.maskToken(token2)
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const pluginConfig = strapi.config.get(`plugin::${PLUGIN_ID}`) || {};
|
|
194
|
+
if (pluginConfig.githubOwner && pluginConfig.githubRepo) {
|
|
195
|
+
return {
|
|
196
|
+
repoUrl: `https://github.com/${pluginConfig.githubOwner}/${pluginConfig.githubRepo}`,
|
|
197
|
+
workflow: pluginConfig.workflow || DEFAULT_SETTINGS.workflow,
|
|
198
|
+
branch: pluginConfig.branch || DEFAULT_SETTINGS.branch,
|
|
199
|
+
hasToken: !!envToken,
|
|
200
|
+
maskedToken: this.maskToken(envToken)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const token = dbSettings?.githubToken || envToken;
|
|
204
|
+
return {
|
|
205
|
+
...DEFAULT_SETTINGS,
|
|
206
|
+
...dbSettings,
|
|
207
|
+
githubToken: void 0,
|
|
208
|
+
hasToken: !!token,
|
|
209
|
+
maskedToken: this.maskToken(token)
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
async saveSettings(settings) {
|
|
213
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
214
|
+
const existingSettings = await store.get({ key: STORE_KEY }) || {};
|
|
215
|
+
const settingsToSave = {
|
|
216
|
+
repoUrl: settings.repoUrl,
|
|
217
|
+
workflow: settings.workflow || DEFAULT_SETTINGS.workflow,
|
|
218
|
+
branch: settings.branch || DEFAULT_SETTINGS.branch,
|
|
219
|
+
// Only update token if a new one is provided
|
|
220
|
+
githubToken: settings.githubToken || existingSettings.githubToken
|
|
221
|
+
};
|
|
222
|
+
await store.set({ key: STORE_KEY, value: settingsToSave });
|
|
223
|
+
return {
|
|
224
|
+
...settingsToSave,
|
|
225
|
+
githubToken: void 0,
|
|
226
|
+
hasToken: !!settingsToSave.githubToken || !!process.env.GITHUB_PERSONAL_ACCESS_TOKEN
|
|
227
|
+
};
|
|
228
|
+
},
|
|
229
|
+
async getToken() {
|
|
230
|
+
const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
|
|
231
|
+
const dbSettings = await store.get({ key: STORE_KEY });
|
|
232
|
+
if (dbSettings?.githubToken) {
|
|
233
|
+
return dbSettings.githubToken;
|
|
234
|
+
}
|
|
235
|
+
return process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
|
|
236
|
+
},
|
|
237
|
+
async isConfigured() {
|
|
238
|
+
const settings = await this.getSettings();
|
|
239
|
+
const hasToken = await this.getToken();
|
|
240
|
+
const { owner, repo } = this.parseRepoUrl(settings.repoUrl);
|
|
241
|
+
return !!(owner && repo && hasToken);
|
|
242
|
+
},
|
|
243
|
+
async hasToken() {
|
|
244
|
+
const token = await this.getToken();
|
|
245
|
+
return !!token;
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
const services = {
|
|
249
|
+
service
|
|
250
|
+
};
|
|
251
|
+
const index = {
|
|
252
|
+
bootstrap,
|
|
253
|
+
destroy,
|
|
254
|
+
register,
|
|
255
|
+
config,
|
|
256
|
+
controllers,
|
|
257
|
+
contentTypes,
|
|
258
|
+
middlewares,
|
|
259
|
+
policies,
|
|
260
|
+
routes,
|
|
261
|
+
services
|
|
262
|
+
};
|
|
263
|
+
export {
|
|
264
|
+
index as default
|
|
265
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orange-soft/strapi-deployment-trigger",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Strapi v5 plugin to trigger GitHub Actions workflow deployments from the admin panel",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Justin Moh <moh@os.my>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/orange-soft/strapi-deployment-trigger.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/orange-soft/strapi-deployment-trigger/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/orange-soft/strapi-deployment-trigger#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"strapi",
|
|
17
|
+
"strapi-plugin",
|
|
18
|
+
"strapi-v5",
|
|
19
|
+
"deployment",
|
|
20
|
+
"github-actions",
|
|
21
|
+
"workflow",
|
|
22
|
+
"deploy",
|
|
23
|
+
"ci-cd"
|
|
24
|
+
],
|
|
25
|
+
"type": "commonjs",
|
|
26
|
+
"exports": {
|
|
27
|
+
"./package.json": "./package.json",
|
|
28
|
+
"./strapi-admin": {
|
|
29
|
+
"source": "./admin/src/index.js",
|
|
30
|
+
"import": "./dist/admin/index.mjs",
|
|
31
|
+
"require": "./dist/admin/index.js",
|
|
32
|
+
"default": "./dist/admin/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./strapi-server": {
|
|
35
|
+
"source": "./server/src/index.js",
|
|
36
|
+
"import": "./dist/server/index.mjs",
|
|
37
|
+
"require": "./dist/server/index.js",
|
|
38
|
+
"default": "./dist/server/index.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"admin",
|
|
44
|
+
"server"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "strapi-plugin build",
|
|
48
|
+
"watch": "strapi-plugin watch",
|
|
49
|
+
"watch:link": "strapi-plugin watch:link",
|
|
50
|
+
"verify": "strapi-plugin verify",
|
|
51
|
+
"prepublishOnly": "npm run build"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@strapi/design-system": "^2.0.0-rc.30",
|
|
55
|
+
"@strapi/icons": "^2.0.0-rc.30",
|
|
56
|
+
"react-intl": "^8.0.8"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@strapi/strapi": "^5.0.0",
|
|
60
|
+
"@strapi/sdk-plugin": "^5.0.0",
|
|
61
|
+
"prettier": "^3.0.0",
|
|
62
|
+
"react": "^18.0.0",
|
|
63
|
+
"react-dom": "^18.0.0",
|
|
64
|
+
"react-router-dom": "^6.0.0",
|
|
65
|
+
"styled-components": "^6.0.0"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@strapi/strapi": "^5.0.0",
|
|
69
|
+
"react": "^18.0.0",
|
|
70
|
+
"react-dom": "^18.0.0",
|
|
71
|
+
"react-router-dom": "^6.0.0",
|
|
72
|
+
"styled-components": "^6.0.0"
|
|
73
|
+
},
|
|
74
|
+
"strapi": {
|
|
75
|
+
"kind": "plugin",
|
|
76
|
+
"name": "deployment-trigger",
|
|
77
|
+
"displayName": "Deployment Trigger",
|
|
78
|
+
"description": "Trigger GitHub Actions deployment from admin panel"
|
|
79
|
+
},
|
|
80
|
+
"engines": {
|
|
81
|
+
"node": ">=18.0.0 <=22.x.x",
|
|
82
|
+
"npm": ">=6.0.0"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|