Skip to content

Commit d2be4b2

Browse files
authored
Merge branch 'main' into concurrency-self-serve
2 parents 36cd7a9 + 1a7ee24 commit d2be4b2

File tree

6 files changed

+1824
-444
lines changed

6 files changed

+1824
-444
lines changed

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export default function Page() {
8484
const [logs, setLogs] = useState<LogEntry[]>([]);
8585
const [isStreaming, setIsStreaming] = useState(true);
8686
const [streamError, setStreamError] = useState<string | null>(null);
87+
const isPending = deployment.status === "PENDING";
8788

8889
useEffect(() => {
8990
if (logsDisabled) return;
@@ -157,7 +158,7 @@ export default function Page() {
157158
return () => {
158159
abortController.abort();
159160
};
160-
}, [s2Logs?.basin, s2Logs?.stream, s2Logs?.accessToken]);
161+
}, [s2Logs?.basin, s2Logs?.stream, s2Logs?.accessToken, isPending]);
161162

162163
return (
163164
<div className="grid h-full max-h-full grid-rows-[2.5rem_1fr] overflow-hidden bg-background-bright">

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings/route.tsx

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
PageContainer,
3131
} from "~/components/layout/AppLayout";
3232
import { Button, LinkButton } from "~/components/primitives/Buttons";
33+
import { CheckboxWithLabel } from "~/components/primitives/Checkbox";
3334
import { ClipboardField } from "~/components/primitives/ClipboardField";
3435
import { Fieldset } from "~/components/primitives/Fieldset";
3536
import { FormButtons } from "~/components/primitives/FormButtons";
@@ -180,6 +181,10 @@ const UpdateBuildSettingsFormSchema = z.object({
180181
.refine((val) => !val || val.length <= 500, {
181182
message: "Pre-build command must not exceed 500 characters",
182183
}),
184+
useNativeBuildServer: z
185+
.string()
186+
.optional()
187+
.transform((val) => val === "on"),
183188
});
184189

185190
type UpdateBuildSettingsFormSchema = z.infer<typeof UpdateBuildSettingsFormSchema>;
@@ -407,12 +412,14 @@ export const action: ActionFunction = async ({ request, params }) => {
407412
});
408413
}
409414
case "update-build-settings": {
410-
const { installCommand, preBuildCommand, triggerConfigFilePath } = submission.value;
415+
const { installCommand, preBuildCommand, triggerConfigFilePath, useNativeBuildServer } =
416+
submission.value;
411417

412418
const resultOrFail = await projectSettingsService.updateBuildSettings(projectId, {
413419
installCommand: installCommand || undefined,
414420
preBuildCommand: preBuildCommand || undefined,
415421
triggerConfigFilePath: triggerConfigFilePath || undefined,
422+
useNativeBuildServer: useNativeBuildServer,
416423
});
417424

418425
if (resultOrFail.isErr()) {
@@ -1135,13 +1142,15 @@ function BuildSettingsForm({ buildSettings }: { buildSettings: BuildSettings })
11351142
preBuildCommand: buildSettings?.preBuildCommand || "",
11361143
installCommand: buildSettings?.installCommand || "",
11371144
triggerConfigFilePath: buildSettings?.triggerConfigFilePath || "",
1145+
useNativeBuildServer: buildSettings?.useNativeBuildServer || false,
11381146
});
11391147

11401148
useEffect(() => {
11411149
const hasChanges =
11421150
buildSettingsValues.preBuildCommand !== (buildSettings?.preBuildCommand || "") ||
11431151
buildSettingsValues.installCommand !== (buildSettings?.installCommand || "") ||
1144-
buildSettingsValues.triggerConfigFilePath !== (buildSettings?.triggerConfigFilePath || "");
1152+
buildSettingsValues.triggerConfigFilePath !== (buildSettings?.triggerConfigFilePath || "") ||
1153+
buildSettingsValues.useNativeBuildServer !== (buildSettings?.useNativeBuildServer || false);
11451154
setHasBuildSettingsChanges(hasChanges);
11461155
}, [buildSettingsValues, buildSettings]);
11471156

@@ -1222,6 +1231,30 @@ function BuildSettingsForm({ buildSettings }: { buildSettings: BuildSettings })
12221231
</Hint>
12231232
<FormError id={fields.preBuildCommand.errorId}>{fields.preBuildCommand.error}</FormError>
12241233
</InputGroup>
1234+
<div className="border-t border-grid-dimmed pt-4">
1235+
<InputGroup>
1236+
<CheckboxWithLabel
1237+
id={fields.useNativeBuildServer.id}
1238+
{...conform.input(fields.useNativeBuildServer, { type: "checkbox" })}
1239+
label="Use native build server"
1240+
variant="simple/small"
1241+
defaultChecked={buildSettings?.useNativeBuildServer || false}
1242+
onChange={(isChecked) => {
1243+
setBuildSettingsValues((prev) => ({
1244+
...prev,
1245+
useNativeBuildServer: isChecked,
1246+
}));
1247+
}}
1248+
/>
1249+
<Hint>
1250+
Native build server builds do not rely on external build providers and will become the
1251+
default in the future. Version 4.1.0 or newer is required.
1252+
</Hint>
1253+
<FormError id={fields.useNativeBuildServer.errorId}>
1254+
{fields.useNativeBuildServer.error}
1255+
</FormError>
1256+
</InputGroup>
1257+
</div>
12251258
<FormError>{buildSettingsForm.error}</FormError>
12261259
<FormButtons
12271260
confirmButton={

apps/webapp/app/v3/buildSettings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const BuildSettingsSchema = z.object({
44
triggerConfigFilePath: z.string().optional(),
55
installCommand: z.string().optional(),
66
preBuildCommand: z.string().optional(),
7+
useNativeBuildServer: z.boolean().optional(),
78
});
89

910
export type BuildSettings = z.infer<typeof BuildSettingsSchema>;

apps/webapp/app/v3/getDeploymentImageRef.server.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
type Tag,
77
RepositoryNotFoundException,
88
GetAuthorizationTokenCommand,
9+
PutLifecyclePolicyCommand,
910
} from "@aws-sdk/client-ecr";
1011
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
1112
import { tryCatch } from "@trigger.dev/core";
@@ -213,7 +214,14 @@ async function createEcrRepository({
213214
const result = await ecr.send(
214215
new CreateRepositoryCommand({
215216
repositoryName,
216-
imageTagMutability: "IMMUTABLE",
217+
imageTagMutability: "IMMUTABLE_WITH_EXCLUSION",
218+
imageTagMutabilityExclusionFilters: [
219+
{
220+
// only the `cache` tag will be mutable, all other tags will be immutable
221+
filter: "cache",
222+
filterType: "WILDCARD",
223+
},
224+
],
217225
encryptionConfiguration: {
218226
encryptionType: "AES256",
219227
},
@@ -227,6 +235,30 @@ async function createEcrRepository({
227235
throw new Error(`Failed to create ECR repository: ${repositoryName}`);
228236
}
229237

238+
// When the `cache` tag is mutated, the old cache images are untagged.
239+
// This policy matches those images and expires them to avoid bloating the repository.
240+
await ecr.send(
241+
new PutLifecyclePolicyCommand({
242+
repositoryName: result.repository.repositoryName,
243+
registryId: result.repository.registryId,
244+
lifecyclePolicyText: JSON.stringify({
245+
rules: [
246+
{
247+
rulePriority: 1,
248+
description: "Expire untagged images older than 3 days",
249+
selection: {
250+
tagStatus: "untagged",
251+
countType: "sinceImagePushed",
252+
countUnit: "days",
253+
countNumber: 3,
254+
},
255+
action: { type: "expire" },
256+
},
257+
],
258+
}),
259+
})
260+
);
261+
230262
return result.repository;
231263
}
232264

apps/webapp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"@ai-sdk/openai": "^1.3.23",
3030
"@ariakit/react": "^0.4.6",
3131
"@ariakit/react-core": "^0.4.6",
32-
"@aws-sdk/client-ecr": "^3.839.0",
32+
"@aws-sdk/client-ecr": "^3.931.0",
3333
"@aws-sdk/client-sqs": "^3.445.0",
3434
"@aws-sdk/client-sts": "^3.840.0",
3535
"@better-auth/utils": "^0.2.6",

0 commit comments

Comments
 (0)