@checkstack/gitops-frontend 0.2.0 → 0.2.1
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @checkstack/gitops-frontend
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 86bab6a: ### GitOps: Fix authentication token handling
|
|
8
|
+
|
|
9
|
+
- Made `authToken` optional in `ReconcileProviderParams` and `ScraperOptions` to support unauthenticated access to public repositories
|
|
10
|
+
- GitHub and GitLab scrapers now conditionally set authentication headers only when a token is provided
|
|
11
|
+
- Sync worker now decrypts the encrypted `authToken` from the database before passing it to scrapers, fixing authentication failures caused by sending encrypted values in HTTP headers
|
|
12
|
+
|
|
13
|
+
### SLO: Fix premature Nines Club achievement unlock
|
|
14
|
+
|
|
15
|
+
- The "Nines Club" achievement now requires both ≥99.99% availability **and** a 365-day compliance streak, preventing immediate unlock on newly created SLOs with 100% default availability
|
|
16
|
+
|
|
17
|
+
### SLO: Align frontend achievement descriptions with backend criteria
|
|
18
|
+
|
|
19
|
+
- Fixed mismatched descriptions for Iron Uptime (7-day, not 30), Diamond Uptime (30-day, not 90), Clean Sheet (rolling window, not quarter), Full Coverage (3+ SLOs, not all systems in group), and Nines Club (99.99%)
|
|
20
|
+
|
|
21
|
+
### SLO: Enrich milestones with system names
|
|
22
|
+
|
|
23
|
+
- The `getRecentMilestones` endpoint now resolves human-readable system names via the Catalog API instead of returning raw system IDs
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [86bab6a]
|
|
26
|
+
- @checkstack/gitops-common@0.1.1
|
|
27
|
+
|
|
3
28
|
## 0.2.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/gitops-frontend",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"checkstack": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@checkstack/common": "0.6.5",
|
|
16
16
|
"@checkstack/frontend-api": "0.3.9",
|
|
17
|
-
"@checkstack/gitops-common": "0.0
|
|
18
|
-
"@checkstack/ui": "1.3.
|
|
17
|
+
"@checkstack/gitops-common": "0.1.0",
|
|
18
|
+
"@checkstack/ui": "1.3.6",
|
|
19
19
|
"lucide-react": "^0.344.0",
|
|
20
20
|
"react": "^18.2.0",
|
|
21
21
|
"react-router-dom": "^6.22.0"
|
|
@@ -24,7 +24,7 @@ interface ProviderEditorProps {
|
|
|
24
24
|
target: string;
|
|
25
25
|
pathPattern: string;
|
|
26
26
|
baseUrl?: string;
|
|
27
|
-
authToken?: string;
|
|
27
|
+
authToken?: string | null;
|
|
28
28
|
syncInterval?: number;
|
|
29
29
|
deletionPolicy?: "orphan" | "auto";
|
|
30
30
|
}) => void;
|
|
@@ -50,6 +50,7 @@ export const ProviderEditor: React.FC<ProviderEditorProps> = ({
|
|
|
50
50
|
const [pathPattern, setPathPattern] = useState(initialData?.pathPattern ?? ".checkstack/**/*.yaml");
|
|
51
51
|
const [baseUrl, setBaseUrl] = useState(initialData?.baseUrl ?? "");
|
|
52
52
|
const [authToken, setAuthToken] = useState("");
|
|
53
|
+
const [clearToken, setClearToken] = useState(false);
|
|
53
54
|
const [syncInterval, setSyncInterval] = useState(String(initialData?.syncInterval ?? 300));
|
|
54
55
|
const [deletionPolicy, setDeletionPolicy] = useState<"orphan" | "auto">(
|
|
55
56
|
initialData?.deletionPolicy ?? "orphan",
|
|
@@ -62,6 +63,7 @@ export const ProviderEditor: React.FC<ProviderEditorProps> = ({
|
|
|
62
63
|
setPathPattern(initialData?.pathPattern ?? ".checkstack/**/*.yaml");
|
|
63
64
|
setBaseUrl(initialData?.baseUrl ?? "");
|
|
64
65
|
setAuthToken("");
|
|
66
|
+
setClearToken(false);
|
|
65
67
|
setSyncInterval(String(initialData?.syncInterval ?? 300));
|
|
66
68
|
setDeletionPolicy(initialData?.deletionPolicy ?? "orphan");
|
|
67
69
|
}
|
|
@@ -71,12 +73,24 @@ export const ProviderEditor: React.FC<ProviderEditorProps> = ({
|
|
|
71
73
|
e.preventDefault();
|
|
72
74
|
if (!target.trim() || !pathPattern.trim()) return;
|
|
73
75
|
|
|
76
|
+
// Determine authToken value:
|
|
77
|
+
// - clearToken=true → null (explicitly remove)
|
|
78
|
+
// - non-empty string → new token
|
|
79
|
+
// - empty string → undefined (keep current)
|
|
80
|
+
let authTokenValue: string | null | undefined;
|
|
81
|
+
if (clearToken) {
|
|
82
|
+
// eslint-disable-next-line unicorn/no-null
|
|
83
|
+
authTokenValue = null;
|
|
84
|
+
} else if (authToken.trim()) {
|
|
85
|
+
authTokenValue = authToken.trim();
|
|
86
|
+
}
|
|
87
|
+
|
|
74
88
|
onSave({
|
|
75
89
|
type,
|
|
76
90
|
target: target.trim(),
|
|
77
91
|
pathPattern: pathPattern.trim(),
|
|
78
92
|
baseUrl: baseUrl.trim() || undefined,
|
|
79
|
-
authToken:
|
|
93
|
+
authToken: authTokenValue,
|
|
80
94
|
syncInterval: Number(syncInterval) || 300,
|
|
81
95
|
deletionPolicy,
|
|
82
96
|
});
|
|
@@ -160,13 +174,45 @@ export const ProviderEditor: React.FC<ProviderEditorProps> = ({
|
|
|
160
174
|
<Label htmlFor="provider-auth-token">
|
|
161
175
|
Auth Token {initialData ? "(leave empty to keep current)" : "(optional)"}
|
|
162
176
|
</Label>
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
{clearToken ? (
|
|
178
|
+
<div className="flex items-center gap-2 p-2 rounded-md border border-border bg-muted/50">
|
|
179
|
+
<span className="text-sm text-muted-foreground flex-1">
|
|
180
|
+
Token will be removed on save
|
|
181
|
+
</span>
|
|
182
|
+
<Button
|
|
183
|
+
type="button"
|
|
184
|
+
variant="outline"
|
|
185
|
+
size="sm"
|
|
186
|
+
onClick={() => setClearToken(false)}
|
|
187
|
+
>
|
|
188
|
+
Undo
|
|
189
|
+
</Button>
|
|
190
|
+
</div>
|
|
191
|
+
) : (
|
|
192
|
+
<div className="flex gap-2">
|
|
193
|
+
<Input
|
|
194
|
+
id="provider-auth-token"
|
|
195
|
+
type="password"
|
|
196
|
+
placeholder="ghp_xxxx..."
|
|
197
|
+
value={authToken}
|
|
198
|
+
onChange={(e) => setAuthToken(e.target.value)}
|
|
199
|
+
className="flex-1"
|
|
200
|
+
/>
|
|
201
|
+
{initialData && (
|
|
202
|
+
<Button
|
|
203
|
+
type="button"
|
|
204
|
+
variant="outline"
|
|
205
|
+
size="sm"
|
|
206
|
+
onClick={() => {
|
|
207
|
+
setAuthToken("");
|
|
208
|
+
setClearToken(true);
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
Remove
|
|
212
|
+
</Button>
|
|
213
|
+
)}
|
|
214
|
+
</div>
|
|
215
|
+
)}
|
|
170
216
|
</div>
|
|
171
217
|
|
|
172
218
|
<div className="grid grid-cols-2 gap-4">
|
|
@@ -119,7 +119,7 @@ export const ProviderList = () => {
|
|
|
119
119
|
target: string;
|
|
120
120
|
pathPattern: string;
|
|
121
121
|
baseUrl?: string;
|
|
122
|
-
authToken?: string;
|
|
122
|
+
authToken?: string | null;
|
|
123
123
|
syncInterval?: number;
|
|
124
124
|
deletionPolicy?: "orphan" | "auto";
|
|
125
125
|
}) => {
|
|
@@ -136,7 +136,11 @@ export const ProviderList = () => {
|
|
|
136
136
|
},
|
|
137
137
|
});
|
|
138
138
|
} else {
|
|
139
|
-
|
|
139
|
+
// On create, authToken is always string|undefined (Remove button not shown)
|
|
140
|
+
createMutation.mutate({
|
|
141
|
+
...data,
|
|
142
|
+
authToken: data.authToken ?? undefined,
|
|
143
|
+
});
|
|
140
144
|
}
|
|
141
145
|
};
|
|
142
146
|
|