Skip to content

Commit 0331f4a

Browse files
frostebiteclaude
andcommitted
Add bulk 'Reset all failed builds' admin button to versions page
Adds a header-level admin button next to the existing 'Clean up stuck builds' button. Calls the resetFailedBuilds endpoint with an empty payload to reset failure counts on all builds stuck at max retries (15+), allowing the Ingeminator to retry them automatically. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c8eb279 commit 0331f4a

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

src/components/docs/versions/image-versions.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState } from 'react';
22
import SignInSignOutButton from '@site/src/components/auth/sign-in-sign-out-button';
33
import CleanUpStuckBuildsButton from './clean-up-stuck-builds-button';
4+
import ResetAllFailedBuildsButton from './reset-all-failed-builds-button';
45
import UnityVersions from './unity-versions';
56
import styles from './unity-version.module.scss';
67

@@ -30,6 +31,7 @@ const ImageVersions = ({ versions }: Props) => {
3031
})}
3132
</select>
3233
<span style={{ float: 'right', display: 'flex', alignItems: 'center', gap: 8 }}>
34+
<ResetAllFailedBuildsButton />
3335
<CleanUpStuckBuildsButton />
3436
<SignInSignOutButton />
3537
</span>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { useState } from 'react';
2+
import { MdRestartAlt } from 'react-icons/md';
3+
import { SimpleAuthCheck } from '@site/src/components/auth/safe-auth-check';
4+
import { useAuthenticatedEndpoint } from '@site/src/core/hooks/use-authenticated-endpoint';
5+
import { useNotification } from '@site/src/core/hooks/use-notification';
6+
import Spinner from '@site/src/components/molecules/spinner';
7+
import Tooltip from '@site/src/components/molecules/tooltip/tooltip';
8+
9+
const ResetAllFailedBuildsButton = () => {
10+
const [running, setRunning] = useState(false);
11+
const notify = useNotification();
12+
const resetAll = useAuthenticatedEndpoint('resetFailedBuilds', {});
13+
14+
const onClick = async () => {
15+
try {
16+
setRunning(true);
17+
await notify.promise(resetAll(), {
18+
loading: <Spinner type="spin" />,
19+
success: (response) => {
20+
const results = response.results || [];
21+
return results.length > 0 ? results.join('\n') : response.message;
22+
},
23+
error: (error) => error.message || 'Reset failed',
24+
});
25+
} finally {
26+
setRunning(false);
27+
}
28+
};
29+
30+
return (
31+
<SimpleAuthCheck fallback={<span />} requiredClaims={{ admin: true }}>
32+
<Tooltip content="Reset failure counts on all builds stuck at max retries (15+) so the Ingeminator retries them">
33+
<button
34+
type="button"
35+
onClick={onClick}
36+
disabled={running}
37+
style={{
38+
padding: '4px 12px',
39+
border: '1px solid #ccc',
40+
borderRadius: 4,
41+
cursor: running ? 'wait' : 'pointer',
42+
background: 'transparent',
43+
display: 'inline-flex',
44+
alignItems: 'center',
45+
gap: 6,
46+
fontSize: '0.85em',
47+
}}
48+
>
49+
<MdRestartAlt color={running ? 'orange' : 'inherit'} />
50+
Reset all failed builds
51+
</button>
52+
</Tooltip>
53+
</SimpleAuthCheck>
54+
);
55+
};
56+
57+
export default ResetAllFailedBuildsButton;

0 commit comments

Comments
 (0)