Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/api/src/handlers/gitea/__tests__/handleComment.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions apps/api/src/handlers/gitea/handleComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import {
findActiveGitHubPrReviewTask,
findReusableGitHubPrFollowUpOwner,
} from '@roomote/db/server';
import { createGiteaPullRequestComment } from '@roomote/gitea';
import {
createGiteaPullRequestComment,
getGiteaDeploymentUser,
} from '@roomote/gitea';
import {
type TaskPayload,
TaskPayloadKind,
Expand Down Expand Up @@ -43,6 +46,23 @@ function isGiteaMention(commentBody: string): boolean {
return commentBody.toLowerCase().includes(GITEA_MENTION_HANDLE);
}

async function isDeploymentTokenAuthor(username: string): Promise<boolean> {
try {
const deploymentUser = await getGiteaDeploymentUser();

return (
!!deploymentUser &&
deploymentUser.login.toLowerCase() === username.toLowerCase()
);
} catch (error) {
console.warn(
`[handleGiteaComment] failed to resolve Gitea deployment token identity: ${error instanceof Error ? error.message : String(error)}`,
);

return false;
}
}

async function postMentionResponseComment({
repositoryFullName,
pullRequestNumber,
Expand Down Expand Up @@ -208,7 +228,10 @@ export async function handleGiteaComment(
return { status: 'ok', message: 'no_comment_author' };
}

if (isRoomoteGiteaUsername(commenter)) {
if (
isRoomoteGiteaUsername(commenter) ||
(await isDeploymentTokenAuthor(commenter))
) {
return { status: 'ok', message: 'roomote_authored_comment' };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,15 @@ export async function spawnDockerWorker(
await docker(['stop', '--time', '10', containerName], {
allowFailure: true,
});
// Nested Docker project daemons are started on standby resume. Stop the
// privileged `<worker>-docker` daemon so it does not keep running after a
// failed resume, but keep the container retained for later `docker start`
// (resume never recreates the daemon).
if (usesDockerProjects) {
await docker(['stop', '--time', '10', taskDaemonContainerName], {
allowFailure: true,
});
}
} else if (resolveAppEnv(process.env) === 'development' && containerId) {
console.error(
`[spawnDockerWorker] Preserving failed Docker worker container ${containerName} for local debugging`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export async function GET() {
{ status: 400 },
);

const redirectUri = buildGitLabOAuthRedirectUri(webEnv.R_APP_URL);
const publicAppUrl = webEnv.R_PUBLIC_URL ?? webEnv.R_APP_URL;
const redirectUri = buildGitLabOAuthRedirectUri(publicAppUrl);
const { url, state } = createGitLabOAuthAuthorizationUrl({
baseUrl,
clientId,
Expand All @@ -38,7 +39,7 @@ export async function GET() {
response.cookies.set('roomote-gitlab-oauth-state', state, {
httpOnly: true,
sameSite: 'lax',
secure: webEnv.R_APP_URL.startsWith('https://'),
secure: publicAppUrl.startsWith('https://'),
path: '/api/source-control/gitlab/oauth',
maxAge: 600,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
const webEnv = await bootstrapWebRuntimeEnv();
const redirect = new URL('/setup', webEnv.R_APP_URL);
const publicAppUrl = webEnv.R_PUBLIC_URL ?? webEnv.R_APP_URL;
const redirect = new URL('/setup', publicAppUrl);
redirect.searchParams.set('step', 'source-control-connect');
const response = () => NextResponse.redirect(redirect);
const authResult = await authorize();
Expand Down Expand Up @@ -46,7 +47,7 @@ export async function GET(request: NextRequest) {
clientId,
clientSecret,
code,
redirectUri: buildGitLabOAuthRedirectUri(webEnv.R_APP_URL),
redirectUri: buildGitLabOAuthRedirectUri(publicAppUrl),
});
redirect.searchParams.set('gitlab', 'connected');
redirect.searchParams.set('sync', '1');
Expand All @@ -58,7 +59,7 @@ export async function GET(request: NextRequest) {
result.cookies.set('roomote-gitlab-oauth-state', '', {
httpOnly: true,
sameSite: 'lax',
secure: webEnv.R_APP_URL.startsWith('https://'),
secure: publicAppUrl.startsWith('https://'),
path: '/api/source-control/gitlab/oauth',
maxAge: 0,
});
Expand Down
11 changes: 4 additions & 7 deletions apps/web/src/components/settings/SourceControlConfigForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,10 @@ export function SourceControlConfigForm({
: 'pat',
);
}
}, [
provider,
nonSecretInitialValues,
isAdo,
nonSecretInitialValuesKey,
providerStatus?.fields,
]);
// providerStatus.fields array identity is intentionally omitted; content
// key and derived non-secret values drive resets instead of query refetches.
// eslint-disable-next-line react-hooks/exhaustive-deps -- content-keyed
}, [provider, nonSecretInitialValues, isAdo, nonSecretInitialValuesKey]);

if (!providerStatus) {
return null;
Expand Down
63 changes: 55 additions & 8 deletions packages/db/src/lib/__tests__/instance-report.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading