Merge branch 'canary' into feat/label-previews

This commit is contained in:
Mauricio Siu
2025-08-23 20:15:37 -06:00
6 changed files with 95 additions and 2 deletions

View File

@@ -177,3 +177,77 @@ COMPLEX_VAR="'Prefix \"DoubleQuoted\" and \${{project.APP_NAME}}'"
]);
});
});
describe("prepareEnvironmentVariables (self references)", () => {
it("resolves self references correctly", () => {
const serviceEnv = `
ENVIRONMENT=staging
DATABASE_URL=postgres://postgres:postgres@localhost:5432/project_db
SELF_REF=\${{ENVIRONMENT}}
`;
const resolved = prepareEnvironmentVariables(serviceEnv, "");
expect(resolved).toEqual([
"ENVIRONMENT=staging",
"DATABASE_URL=postgres://postgres:postgres@localhost:5432/project_db",
"SELF_REF=staging",
]);
});
it("throws on undefined self references", () => {
const serviceEnv = `
MISSING_VAR=\${{UNDEFINED_VAR}}
`;
expect(() => prepareEnvironmentVariables(serviceEnv, "")).toThrow(
"Invalid service environment variable: UNDEFINED_VAR",
);
});
it("allows overriding and still resolving from self", () => {
const serviceEnv = `
ENVIRONMENT=production
OVERRIDE_ENV=\${{ENVIRONMENT}}
`;
const resolved = prepareEnvironmentVariables(serviceEnv, "");
expect(resolved).toEqual([
"ENVIRONMENT=production",
"OVERRIDE_ENV=production",
]);
});
it("resolves multiple self references inside one value", () => {
const serviceEnv = `
ENVIRONMENT=staging
APP_NAME=MyApp
COMPLEX=\${{APP_NAME}}-\${{ENVIRONMENT}}-\${{APP_NAME}}
`;
const resolved = prepareEnvironmentVariables(serviceEnv, "");
expect(resolved).toEqual([
"ENVIRONMENT=staging",
"APP_NAME=MyApp",
"COMPLEX=MyApp-staging-MyApp",
]);
});
it("handles quotes with self references", () => {
const serviceEnv = `
ENVIRONMENT=production
QUOTED="'\${{ENVIRONMENT}}'"
MIXED="\"Double \${{ENVIRONMENT}}\""
`;
const resolved = prepareEnvironmentVariables(serviceEnv, "");
expect(resolved).toEqual([
"ENVIRONMENT=production",
"QUOTED='production'",
'MIXED="Double production"',
]);
});
});

View File

@@ -24,6 +24,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { api } from "@/utils/api";
const organizationSchema = z.object({
@@ -54,6 +55,8 @@ export function AddOrganization({ organizationId }: Props) {
const { mutateAsync, isLoading } = organizationId
? api.organization.update.useMutation()
: api.organization.create.useMutation();
const { refetch: refetchActiveOrganization } =
authClient.useActiveOrganization();
const form = useForm<OrganizationFormValues>({
resolver: zodResolver(organizationSchema),
@@ -84,6 +87,10 @@ export function AddOrganization({ organizationId }: Props) {
`Organization ${organizationId ? "updated" : "created"} successfully`,
);
utils.organization.all.invalidate();
if (organizationId) {
utils.organization.one.invalidate({ organizationId });
refetchActiveOrganization();
}
setOpen(false);
})
.catch((error) => {

View File

@@ -21,7 +21,7 @@ import {
await initializeNetwork();
createDefaultTraefikConfig();
createDefaultServerTraefikConfig();
await execAsync("docker pull traefik:v3.1.2");
await execAsync("docker pull traefik:v3.5.0");
await initializeStandaloneTraefik();
await initializeRedis();
await initializePostgres();

View File

@@ -13,7 +13,8 @@ export const TRAEFIK_PORT =
Number.parseInt(process.env.TRAEFIK_PORT!, 10) || 80;
export const TRAEFIK_HTTP3_PORT =
Number.parseInt(process.env.TRAEFIK_HTTP3_PORT!, 10) || 443;
export const TRAEFIK_VERSION = process.env.TRAEFIK_VERSION || "3.1.2";
export const TRAEFIK_VERSION = process.env.TRAEFIK_VERSION || "3.5.0";
export interface TraefikOptions {
env?: string[];

View File

@@ -254,6 +254,9 @@ export const addDomainToCompose = async (
if (!labels.includes("traefik.docker.network=dokploy-network")) {
labels.unshift("traefik.docker.network=dokploy-network");
}
if (!labels.includes("traefik.swarm.network=dokploy-network")) {
labels.unshift("traefik.swarm.network=dokploy-network");
}
}
}

View File

@@ -273,6 +273,14 @@ export const prepareEnvironmentVariables = (
throw new Error(`Invalid project environment variable: project.${ref}`);
});
}
resolvedValue = resolvedValue.replace(/\$\{\{(.*?)\}\}/g, (_, ref) => {
if (serviceVars[ref] !== undefined) {
return serviceVars[ref];
}
throw new Error(`Invalid service environment variable: ${ref}`);
});
return `${key}=${resolvedValue}`;
});