@orange-soft/strapi-deployment-trigger 1.0.1 → 1.1.2
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/admin/src/pages/HomePage.jsx +117 -62
- package/admin/src/pages/SettingsPage.jsx +274 -101
- package/dist/_chunks/App-CCbQMMHR.js +669 -0
- package/dist/_chunks/App-DRqMK_8x.mjs +669 -0
- package/dist/_chunks/{index-CqpMwL_C.js → index-SuWmJtOE.js} +1 -1
- package/dist/_chunks/{index-C18aSW5z.mjs → index-vQ0KWcpU.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +164 -24
- package/dist/server/index.mjs +164 -24
- package/package.json +1 -1
- package/server/src/controllers/controller.js +58 -3
- package/server/src/routes/admin/index.js +25 -0
- package/server/src/services/service.js +122 -24
- package/dist/_chunks/App-3JntxPYv.js +0 -520
- package/dist/_chunks/App-C0Byi5W1.mjs +0 -520
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useFetchClient, Layouts, BackButton, Page } from "@strapi/strapi/admin";
|
|
3
|
-
import { Link, Routes, Route } from "react-router-dom";
|
|
4
|
-
import { useState, useEffect } from "react";
|
|
5
|
-
import { useIntl } from "react-intl";
|
|
6
|
-
import { Flex, Loader, Button, Box, Alert, Typography, Field, Grid } from "@strapi/design-system";
|
|
7
|
-
import { Cog, Rocket, Check } from "@strapi/icons";
|
|
8
|
-
import { P as PLUGIN_ID } from "./index-C18aSW5z.mjs";
|
|
9
|
-
const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
|
|
10
|
-
const HomePage = () => {
|
|
11
|
-
const { formatMessage } = useIntl();
|
|
12
|
-
const { get, post } = useFetchClient();
|
|
13
|
-
const [status, setStatus] = useState(null);
|
|
14
|
-
const [loading, setLoading] = useState(true);
|
|
15
|
-
const [deploying, setDeploying] = useState(false);
|
|
16
|
-
const [notification, setNotification] = useState(null);
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
fetchStatus();
|
|
19
|
-
}, []);
|
|
20
|
-
const fetchStatus = async () => {
|
|
21
|
-
try {
|
|
22
|
-
const { data } = await get(`/${PLUGIN_ID}/status`);
|
|
23
|
-
setStatus(data.data);
|
|
24
|
-
} catch (error) {
|
|
25
|
-
console.error("Failed to fetch status:", error);
|
|
26
|
-
} finally {
|
|
27
|
-
setLoading(false);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
const handleDeploy = async () => {
|
|
31
|
-
setDeploying(true);
|
|
32
|
-
setNotification(null);
|
|
33
|
-
try {
|
|
34
|
-
const { data } = await post(`/${PLUGIN_ID}/trigger`, {});
|
|
35
|
-
setNotification({
|
|
36
|
-
type: "success",
|
|
37
|
-
message: data.data?.message || "Deployment triggered successfully!",
|
|
38
|
-
actionsUrl: data.data?.actionsUrl
|
|
39
|
-
});
|
|
40
|
-
} catch (error) {
|
|
41
|
-
setNotification({
|
|
42
|
-
type: "danger",
|
|
43
|
-
message: error?.response?.data?.error?.message || error.message || "Deployment failed"
|
|
44
|
-
});
|
|
45
|
-
} finally {
|
|
46
|
-
setDeploying(false);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
if (loading) {
|
|
50
|
-
return /* @__PURE__ */ jsxs(Layouts.Root, { children: [
|
|
51
|
-
/* @__PURE__ */ jsx(
|
|
52
|
-
Layouts.Header,
|
|
53
|
-
{
|
|
54
|
-
title: formatMessage({ id: getTranslation("plugin.name") }),
|
|
55
|
-
subtitle: "Loading..."
|
|
56
|
-
}
|
|
57
|
-
),
|
|
58
|
-
/* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsx(Loader, { children: "Loading..." }) }) })
|
|
59
|
-
] });
|
|
60
|
-
}
|
|
61
|
-
const settings = status?.settings || {};
|
|
62
|
-
const parsed = status?.parsed || {};
|
|
63
|
-
const isConfigured = status?.configured;
|
|
64
|
-
const hasToken = status?.hasToken;
|
|
65
|
-
return /* @__PURE__ */ jsxs(Layouts.Root, { children: [
|
|
66
|
-
/* @__PURE__ */ jsx(
|
|
67
|
-
Layouts.Header,
|
|
68
|
-
{
|
|
69
|
-
title: formatMessage({ id: getTranslation("plugin.name") }),
|
|
70
|
-
subtitle: "Trigger GitHub Actions deployment to production",
|
|
71
|
-
secondaryAction: /* @__PURE__ */ jsx(Link, { to: `/plugins/${PLUGIN_ID}/settings`, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", startIcon: /* @__PURE__ */ jsx(Cog, {}), children: "Settings" }) })
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsxs(Layouts.Content, { children: [
|
|
75
|
-
notification && /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(
|
|
76
|
-
Alert,
|
|
77
|
-
{
|
|
78
|
-
closeLabel: "Close",
|
|
79
|
-
title: notification.message,
|
|
80
|
-
variant: notification.type,
|
|
81
|
-
onClose: () => setNotification(null),
|
|
82
|
-
children: notification.actionsUrl && /* @__PURE__ */ jsxs(Typography, { variant: "pi", children: [
|
|
83
|
-
"Check the deployment status at",
|
|
84
|
-
" ",
|
|
85
|
-
/* @__PURE__ */ jsx(
|
|
86
|
-
Typography,
|
|
87
|
-
{
|
|
88
|
-
variant: "pi",
|
|
89
|
-
tag: "a",
|
|
90
|
-
href: notification.actionsUrl,
|
|
91
|
-
target: "_blank",
|
|
92
|
-
rel: "noopener noreferrer",
|
|
93
|
-
textColor: "primary600",
|
|
94
|
-
children: "GitHub Actions"
|
|
95
|
-
}
|
|
96
|
-
)
|
|
97
|
-
] })
|
|
98
|
-
}
|
|
99
|
-
) }),
|
|
100
|
-
!hasToken && /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(Alert, { title: "Token Missing", variant: "danger", children: "GitHub Personal Access Token is not configured. Please add it in Settings." }) }),
|
|
101
|
-
!settings.repoUrl && /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(Alert, { title: "Configuration Required", variant: "warning", children: "Please configure your GitHub repository in the Settings page before triggering deployments." }) }),
|
|
102
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
103
|
-
/* @__PURE__ */ jsx(
|
|
104
|
-
Box,
|
|
105
|
-
{
|
|
106
|
-
background: "neutral0",
|
|
107
|
-
hasRadius: true,
|
|
108
|
-
shadow: "filterShadow",
|
|
109
|
-
paddingTop: 6,
|
|
110
|
-
paddingBottom: 6,
|
|
111
|
-
paddingLeft: 7,
|
|
112
|
-
paddingRight: 7,
|
|
113
|
-
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
114
|
-
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: "Configuration" }),
|
|
115
|
-
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 6, children: [
|
|
116
|
-
/* @__PURE__ */ jsxs(Box, { style: { display: "grid", gridTemplateColumns: "120px 1fr", gap: "12px 16px", alignItems: "center" }, children: [
|
|
117
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Repository" }),
|
|
118
|
-
parsed.owner && parsed.repo ? /* @__PURE__ */ jsxs(
|
|
119
|
-
Typography,
|
|
120
|
-
{
|
|
121
|
-
variant: "pi",
|
|
122
|
-
tag: "a",
|
|
123
|
-
href: settings.repoUrl,
|
|
124
|
-
target: "_blank",
|
|
125
|
-
rel: "noopener noreferrer",
|
|
126
|
-
textColor: "primary600",
|
|
127
|
-
style: { textDecoration: "none" },
|
|
128
|
-
children: [
|
|
129
|
-
parsed.owner,
|
|
130
|
-
"/",
|
|
131
|
-
parsed.repo
|
|
132
|
-
]
|
|
133
|
-
}
|
|
134
|
-
) : /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: "Not configured" }),
|
|
135
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Workflow" }),
|
|
136
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", children: settings.workflow || "deploy.yml (default)" }),
|
|
137
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Branch" }),
|
|
138
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", children: settings.branch || "master (default)" }),
|
|
139
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "GitHub Token" }),
|
|
140
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: hasToken ? "success600" : "danger600", children: hasToken ? "Configured" : "Missing" })
|
|
141
|
-
] }),
|
|
142
|
-
isConfigured && /* @__PURE__ */ jsx(
|
|
143
|
-
Button,
|
|
144
|
-
{
|
|
145
|
-
onClick: handleDeploy,
|
|
146
|
-
loading: deploying,
|
|
147
|
-
disabled: deploying,
|
|
148
|
-
startIcon: /* @__PURE__ */ jsx(Rocket, {}),
|
|
149
|
-
size: "L",
|
|
150
|
-
children: deploying ? "Triggering..." : "Trigger Deployment"
|
|
151
|
-
}
|
|
152
|
-
)
|
|
153
|
-
] })
|
|
154
|
-
] })
|
|
155
|
-
}
|
|
156
|
-
),
|
|
157
|
-
!isConfigured && /* @__PURE__ */ jsx(
|
|
158
|
-
Box,
|
|
159
|
-
{
|
|
160
|
-
background: "neutral0",
|
|
161
|
-
hasRadius: true,
|
|
162
|
-
shadow: "filterShadow",
|
|
163
|
-
paddingTop: 8,
|
|
164
|
-
paddingBottom: 8,
|
|
165
|
-
paddingLeft: 7,
|
|
166
|
-
paddingRight: 7,
|
|
167
|
-
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", justifyContent: "center", gap: 3, children: [
|
|
168
|
-
/* @__PURE__ */ jsx(Typography, { variant: "beta", textColor: "neutral600", textAlign: "center", children: "Setup Required" }),
|
|
169
|
-
/* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", textAlign: "center", children: "Configure your GitHub repository settings to enable deployment triggering." }),
|
|
170
|
-
/* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(Link, { to: `/plugins/${PLUGIN_ID}/settings`, children: /* @__PURE__ */ jsx(Button, { variant: "default", startIcon: /* @__PURE__ */ jsx(Cog, {}), children: "Go to Settings" }) }) })
|
|
171
|
-
] })
|
|
172
|
-
}
|
|
173
|
-
)
|
|
174
|
-
] })
|
|
175
|
-
] })
|
|
176
|
-
] });
|
|
177
|
-
};
|
|
178
|
-
const TOKEN_PATTERN = /^github_pat_[a-zA-Z0-9_]+$/;
|
|
179
|
-
const REPO_URL_PATTERN = /^https:\/\/github\.com\/[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+\/?$/;
|
|
180
|
-
const WORKFLOW_PATTERN = /^[a-zA-Z0-9_.-]+\.ya?ml$/;
|
|
181
|
-
const validateToken = (value) => {
|
|
182
|
-
if (!value) return null;
|
|
183
|
-
if (!TOKEN_PATTERN.test(value)) {
|
|
184
|
-
return 'Token must start with "github_pat_" followed by alphanumeric characters';
|
|
185
|
-
}
|
|
186
|
-
return null;
|
|
187
|
-
};
|
|
188
|
-
const validateRepoUrl = (value) => {
|
|
189
|
-
if (!value) return "Repository URL is required";
|
|
190
|
-
if (!REPO_URL_PATTERN.test(value)) {
|
|
191
|
-
return "Must be a valid GitHub URL (e.g., https://github.com/owner/repo)";
|
|
192
|
-
}
|
|
193
|
-
return null;
|
|
194
|
-
};
|
|
195
|
-
const validateWorkflow = (value) => {
|
|
196
|
-
if (!value) return null;
|
|
197
|
-
if (!WORKFLOW_PATTERN.test(value)) {
|
|
198
|
-
return "Workflow file must end with .yml or .yaml";
|
|
199
|
-
}
|
|
200
|
-
return null;
|
|
201
|
-
};
|
|
202
|
-
const SettingsPage = () => {
|
|
203
|
-
const { get, put } = useFetchClient();
|
|
204
|
-
const [settings, setSettings] = useState({
|
|
205
|
-
githubToken: "",
|
|
206
|
-
repoUrl: "",
|
|
207
|
-
workflow: "",
|
|
208
|
-
branch: ""
|
|
209
|
-
});
|
|
210
|
-
const [errors, setErrors] = useState({});
|
|
211
|
-
const [hasExistingToken, setHasExistingToken] = useState(false);
|
|
212
|
-
const [maskedToken, setMaskedToken] = useState(null);
|
|
213
|
-
const [loading, setLoading] = useState(true);
|
|
214
|
-
const [saving, setSaving] = useState(false);
|
|
215
|
-
const [notification, setNotification] = useState(null);
|
|
216
|
-
useEffect(() => {
|
|
217
|
-
fetchSettings();
|
|
218
|
-
}, []);
|
|
219
|
-
const fetchSettings = async () => {
|
|
220
|
-
setLoading(true);
|
|
221
|
-
try {
|
|
222
|
-
const { data } = await get(`/${PLUGIN_ID}/settings`);
|
|
223
|
-
const fetchedSettings = data.data || {};
|
|
224
|
-
setSettings({
|
|
225
|
-
githubToken: "",
|
|
226
|
-
repoUrl: fetchedSettings.repoUrl || "",
|
|
227
|
-
workflow: fetchedSettings.workflow || "",
|
|
228
|
-
branch: fetchedSettings.branch || ""
|
|
229
|
-
});
|
|
230
|
-
setHasExistingToken(fetchedSettings.hasToken || false);
|
|
231
|
-
setMaskedToken(fetchedSettings.maskedToken || null);
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error("Error fetching settings:", error);
|
|
234
|
-
setNotification({
|
|
235
|
-
type: "danger",
|
|
236
|
-
message: "Failed to load settings"
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
setLoading(false);
|
|
240
|
-
};
|
|
241
|
-
const validateAll = () => {
|
|
242
|
-
const newErrors = {};
|
|
243
|
-
const tokenError = validateToken(settings.githubToken);
|
|
244
|
-
if (tokenError && settings.githubToken) newErrors.githubToken = tokenError;
|
|
245
|
-
const repoError = validateRepoUrl(settings.repoUrl);
|
|
246
|
-
if (repoError) newErrors.repoUrl = repoError;
|
|
247
|
-
const workflowError = validateWorkflow(settings.workflow);
|
|
248
|
-
if (workflowError) newErrors.workflow = workflowError;
|
|
249
|
-
setErrors(newErrors);
|
|
250
|
-
return Object.keys(newErrors).length === 0;
|
|
251
|
-
};
|
|
252
|
-
const handleSave = async () => {
|
|
253
|
-
if (!validateAll()) {
|
|
254
|
-
setNotification({
|
|
255
|
-
type: "warning",
|
|
256
|
-
message: "Please fix the validation errors before saving"
|
|
257
|
-
});
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
setSaving(true);
|
|
261
|
-
try {
|
|
262
|
-
const dataToSave = { ...settings };
|
|
263
|
-
if (!dataToSave.githubToken) {
|
|
264
|
-
delete dataToSave.githubToken;
|
|
265
|
-
}
|
|
266
|
-
await put(`/${PLUGIN_ID}/settings`, { data: dataToSave });
|
|
267
|
-
if (settings.githubToken) {
|
|
268
|
-
setHasExistingToken(true);
|
|
269
|
-
}
|
|
270
|
-
setSettings((prev) => ({ ...prev, githubToken: "" }));
|
|
271
|
-
setNotification({
|
|
272
|
-
type: "success",
|
|
273
|
-
message: "Settings saved successfully"
|
|
274
|
-
});
|
|
275
|
-
} catch (error) {
|
|
276
|
-
console.error("Error saving settings:", error);
|
|
277
|
-
setNotification({
|
|
278
|
-
type: "danger",
|
|
279
|
-
message: "Failed to save settings"
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
setSaving(false);
|
|
283
|
-
};
|
|
284
|
-
const handleChange = (field) => (e) => {
|
|
285
|
-
const value = e.target.value;
|
|
286
|
-
setSettings((prev) => ({ ...prev, [field]: value }));
|
|
287
|
-
if (errors[field]) {
|
|
288
|
-
setErrors((prev) => ({ ...prev, [field]: null }));
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
const handleBlur = (field, validator) => () => {
|
|
292
|
-
const error = validator(settings[field]);
|
|
293
|
-
if (error) {
|
|
294
|
-
setErrors((prev) => ({ ...prev, [field]: error }));
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
if (loading) {
|
|
298
|
-
return /* @__PURE__ */ jsxs(Layouts.Root, { children: [
|
|
299
|
-
/* @__PURE__ */ jsx(
|
|
300
|
-
Layouts.Header,
|
|
301
|
-
{
|
|
302
|
-
title: "Settings",
|
|
303
|
-
subtitle: "Configure GitHub Actions deployment",
|
|
304
|
-
navigationAction: /* @__PURE__ */ jsx(BackButton, { fallback: `/plugins/${PLUGIN_ID}` })
|
|
305
|
-
}
|
|
306
|
-
),
|
|
307
|
-
/* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsx(Loader, { children: "Loading settings..." }) }) })
|
|
308
|
-
] });
|
|
309
|
-
}
|
|
310
|
-
const isValid = settings.repoUrl && !errors.repoUrl && !errors.githubToken && !errors.workflow;
|
|
311
|
-
return /* @__PURE__ */ jsxs(Layouts.Root, { children: [
|
|
312
|
-
/* @__PURE__ */ jsx(
|
|
313
|
-
Layouts.Header,
|
|
314
|
-
{
|
|
315
|
-
title: "Settings",
|
|
316
|
-
subtitle: "Configure GitHub Actions deployment",
|
|
317
|
-
navigationAction: /* @__PURE__ */ jsx(BackButton, { fallback: `/plugins/${PLUGIN_ID}` }),
|
|
318
|
-
primaryAction: /* @__PURE__ */ jsx(
|
|
319
|
-
Button,
|
|
320
|
-
{
|
|
321
|
-
onClick: handleSave,
|
|
322
|
-
loading: saving,
|
|
323
|
-
disabled: loading || !isValid,
|
|
324
|
-
startIcon: /* @__PURE__ */ jsx(Check, {}),
|
|
325
|
-
size: "L",
|
|
326
|
-
children: "Save Settings"
|
|
327
|
-
}
|
|
328
|
-
)
|
|
329
|
-
}
|
|
330
|
-
),
|
|
331
|
-
/* @__PURE__ */ jsxs(Layouts.Content, { children: [
|
|
332
|
-
notification && /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(
|
|
333
|
-
Alert,
|
|
334
|
-
{
|
|
335
|
-
closeLabel: "Close",
|
|
336
|
-
title: notification.message,
|
|
337
|
-
variant: notification.type,
|
|
338
|
-
onClose: () => setNotification(null)
|
|
339
|
-
}
|
|
340
|
-
) }),
|
|
341
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
342
|
-
/* @__PURE__ */ jsx(
|
|
343
|
-
Box,
|
|
344
|
-
{
|
|
345
|
-
background: "neutral0",
|
|
346
|
-
hasRadius: true,
|
|
347
|
-
shadow: "filterShadow",
|
|
348
|
-
paddingTop: 6,
|
|
349
|
-
paddingBottom: 6,
|
|
350
|
-
paddingLeft: 7,
|
|
351
|
-
paddingRight: 7,
|
|
352
|
-
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
353
|
-
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: "Repository" }),
|
|
354
|
-
/* @__PURE__ */ jsxs(
|
|
355
|
-
Field.Root,
|
|
356
|
-
{
|
|
357
|
-
name: "repoUrl",
|
|
358
|
-
required: true,
|
|
359
|
-
error: errors.repoUrl,
|
|
360
|
-
hint: "Copy the URL from your browser when viewing the repository",
|
|
361
|
-
children: [
|
|
362
|
-
/* @__PURE__ */ jsx(Field.Label, { children: "Repository URL" }),
|
|
363
|
-
/* @__PURE__ */ jsx(
|
|
364
|
-
Field.Input,
|
|
365
|
-
{
|
|
366
|
-
placeholder: "https://github.com/{owner}/{repo}",
|
|
367
|
-
value: settings.repoUrl,
|
|
368
|
-
onChange: handleChange("repoUrl"),
|
|
369
|
-
onBlur: handleBlur("repoUrl", validateRepoUrl)
|
|
370
|
-
}
|
|
371
|
-
),
|
|
372
|
-
/* @__PURE__ */ jsx(Field.Hint, {}),
|
|
373
|
-
/* @__PURE__ */ jsx(Field.Error, {})
|
|
374
|
-
]
|
|
375
|
-
}
|
|
376
|
-
)
|
|
377
|
-
] })
|
|
378
|
-
}
|
|
379
|
-
),
|
|
380
|
-
/* @__PURE__ */ jsx(
|
|
381
|
-
Box,
|
|
382
|
-
{
|
|
383
|
-
background: "neutral0",
|
|
384
|
-
hasRadius: true,
|
|
385
|
-
shadow: "filterShadow",
|
|
386
|
-
paddingTop: 6,
|
|
387
|
-
paddingBottom: 6,
|
|
388
|
-
paddingLeft: 7,
|
|
389
|
-
paddingRight: 7,
|
|
390
|
-
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
391
|
-
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: "Workflow Configuration" }),
|
|
392
|
-
/* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
|
|
393
|
-
/* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(
|
|
394
|
-
Field.Root,
|
|
395
|
-
{
|
|
396
|
-
name: "workflow",
|
|
397
|
-
required: true,
|
|
398
|
-
error: errors.workflow,
|
|
399
|
-
hint: "Filename in .github/workflows/",
|
|
400
|
-
children: [
|
|
401
|
-
/* @__PURE__ */ jsx(Field.Label, { children: "Workflow File" }),
|
|
402
|
-
/* @__PURE__ */ jsx(
|
|
403
|
-
Field.Input,
|
|
404
|
-
{
|
|
405
|
-
placeholder: "deploy.yml",
|
|
406
|
-
value: settings.workflow,
|
|
407
|
-
onChange: handleChange("workflow"),
|
|
408
|
-
onBlur: handleBlur("workflow", validateWorkflow)
|
|
409
|
-
}
|
|
410
|
-
),
|
|
411
|
-
/* @__PURE__ */ jsx(Field.Hint, {}),
|
|
412
|
-
/* @__PURE__ */ jsx(Field.Error, {})
|
|
413
|
-
]
|
|
414
|
-
}
|
|
415
|
-
) }),
|
|
416
|
-
/* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(
|
|
417
|
-
Field.Root,
|
|
418
|
-
{
|
|
419
|
-
name: "branch",
|
|
420
|
-
required: true,
|
|
421
|
-
hint: "Branch to trigger the workflow on",
|
|
422
|
-
children: [
|
|
423
|
-
/* @__PURE__ */ jsx(Field.Label, { children: "Branch" }),
|
|
424
|
-
/* @__PURE__ */ jsx(
|
|
425
|
-
Field.Input,
|
|
426
|
-
{
|
|
427
|
-
placeholder: "main",
|
|
428
|
-
value: settings.branch,
|
|
429
|
-
onChange: handleChange("branch")
|
|
430
|
-
}
|
|
431
|
-
),
|
|
432
|
-
/* @__PURE__ */ jsx(Field.Hint, {})
|
|
433
|
-
]
|
|
434
|
-
}
|
|
435
|
-
) })
|
|
436
|
-
] })
|
|
437
|
-
] })
|
|
438
|
-
}
|
|
439
|
-
),
|
|
440
|
-
/* @__PURE__ */ jsx(
|
|
441
|
-
Box,
|
|
442
|
-
{
|
|
443
|
-
background: "neutral0",
|
|
444
|
-
hasRadius: true,
|
|
445
|
-
shadow: "filterShadow",
|
|
446
|
-
paddingTop: 6,
|
|
447
|
-
paddingBottom: 6,
|
|
448
|
-
paddingLeft: 7,
|
|
449
|
-
paddingRight: 7,
|
|
450
|
-
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
|
|
451
|
-
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: "Authentication" }),
|
|
452
|
-
/* @__PURE__ */ jsxs(
|
|
453
|
-
Field.Root,
|
|
454
|
-
{
|
|
455
|
-
name: "githubToken",
|
|
456
|
-
required: true,
|
|
457
|
-
error: errors.githubToken,
|
|
458
|
-
hint: !hasExistingToken || !maskedToken ? "Create a fine-grained token with Actions (Read and write) permission" : void 0,
|
|
459
|
-
children: [
|
|
460
|
-
/* @__PURE__ */ jsx(Field.Label, { children: "GitHub Personal Access Token" }),
|
|
461
|
-
/* @__PURE__ */ jsx(
|
|
462
|
-
Field.Input,
|
|
463
|
-
{
|
|
464
|
-
type: "password",
|
|
465
|
-
placeholder: hasExistingToken ? "••••••••••••••••" : "github_pat_xxxxxxxxxxxx",
|
|
466
|
-
value: settings.githubToken,
|
|
467
|
-
onChange: handleChange("githubToken"),
|
|
468
|
-
onBlur: handleBlur("githubToken", validateToken)
|
|
469
|
-
}
|
|
470
|
-
),
|
|
471
|
-
hasExistingToken && maskedToken ? /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
472
|
-
"Existing token:",
|
|
473
|
-
" ",
|
|
474
|
-
/* @__PURE__ */ jsx(
|
|
475
|
-
Typography,
|
|
476
|
-
{
|
|
477
|
-
variant: "pi",
|
|
478
|
-
fontWeight: "bold",
|
|
479
|
-
textColor: "success600",
|
|
480
|
-
tag: "span",
|
|
481
|
-
children: maskedToken
|
|
482
|
-
}
|
|
483
|
-
),
|
|
484
|
-
". Leave empty to keep existing, or enter new to replace."
|
|
485
|
-
] }) : /* @__PURE__ */ jsx(Field.Hint, {}),
|
|
486
|
-
/* @__PURE__ */ jsx(Field.Error, {})
|
|
487
|
-
]
|
|
488
|
-
}
|
|
489
|
-
),
|
|
490
|
-
/* @__PURE__ */ jsxs(Box, { paddingTop: 2, children: [
|
|
491
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "How to get a GitHub Token:" }),
|
|
492
|
-
/* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsxs(Typography, { variant: "pi", tag: "ol", textColor: "neutral600", children: [
|
|
493
|
-
/* @__PURE__ */ jsx("li", { children: "Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens" }),
|
|
494
|
-
/* @__PURE__ */ jsx("li", { children: 'Click "Generate new token"' }),
|
|
495
|
-
/* @__PURE__ */ jsx("li", { children: "Set token name, expiration, and select the target repository" }),
|
|
496
|
-
/* @__PURE__ */ jsxs("li", { children: [
|
|
497
|
-
'Under "Repository permissions", set ',
|
|
498
|
-
/* @__PURE__ */ jsx("strong", { children: "Actions" }),
|
|
499
|
-
' to "Read and write"'
|
|
500
|
-
] }),
|
|
501
|
-
/* @__PURE__ */ jsx("li", { children: 'Click "Generate token" and paste it above' })
|
|
502
|
-
] }) })
|
|
503
|
-
] })
|
|
504
|
-
] })
|
|
505
|
-
}
|
|
506
|
-
)
|
|
507
|
-
] })
|
|
508
|
-
] })
|
|
509
|
-
] });
|
|
510
|
-
};
|
|
511
|
-
const App = () => {
|
|
512
|
-
return /* @__PURE__ */ jsxs(Routes, { children: [
|
|
513
|
-
/* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(HomePage, {}) }),
|
|
514
|
-
/* @__PURE__ */ jsx(Route, { path: "settings", element: /* @__PURE__ */ jsx(SettingsPage, {}) }),
|
|
515
|
-
/* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
|
|
516
|
-
] });
|
|
517
|
-
};
|
|
518
|
-
export {
|
|
519
|
-
App
|
|
520
|
-
};
|