Skip to content
Draft
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
16 changes: 16 additions & 0 deletions packages/stacks-svelte/netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,19 @@
to = "https://svelte.stackoverflow.design/:splat"
status = 301
force = true

# Add v0 as a production domain alias only after these rules are deployed.
# Upgrade explicitly: Netlify's automatic HTTPS redirect may not apply to proxies.
[[redirects]]
from = "http://v0.svelte.stackoverflow.design/*"
to = "https://v0.svelte.stackoverflow.design/:splat"
status = 301
force = true

# Keep the v2 branch deploy enabled: it remains the legacy content source.
# Use its Netlify hostname, not a custom domain that may redirect back to v0.
[[redirects]]
from = "https://v0.svelte.stackoverflow.design/*"
to = "https://v2--stacks-svelte.netlify.app/:splat"
status = 200
force = true
50 changes: 46 additions & 4 deletions packages/stacks-svelte/tools/netlify-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,54 @@ const netlifyConfig = readFileSync(
join(toolsDirectory, "..", "netlify.toml"),
"utf8"
);
const redirects = netlifyConfig
.split(/^\s*\[\[redirects\]\]\s*$/m)
.slice(1)
.map((block) => block.split("\n").map((line) => line.trim()));

const expectedRules = [
{
name: "redirects the beta hostname to the current documentation",
from: "https://beta.svelte.stackoverflow.design/*",
to: "https://svelte.stackoverflow.design/:splat",
status: 301,
},
{
name: "upgrades the v0 hostname to HTTPS before proxying",
from: "http://v0.svelte.stackoverflow.design/*",
to: "https://v0.svelte.stackoverflow.design/:splat",
status: 301,
},
{
name: "serves the existing v2 branch deploy behind the HTTPS v0 hostname",
from: "https://v0.svelte.stackoverflow.design/*",
to: "https://v2--stacks-svelte.netlify.app/:splat",
status: 200,
},
];

describe("Netlify configuration", () => {
test("redirects the beta hostname to the current documentation", () => {
assert.match(
netlifyConfig,
/\[\[redirects\]\][\s\S]*from = "https:\/\/beta\.svelte\.stackoverflow\.design\/\*"[\s\S]*to = "https:\/\/svelte\.stackoverflow\.design\/:splat"[\s\S]*status = 301[\s\S]*force = true/
test("limits routing rules to the beta and v0 hostnames", () => {
assert.deepStrictEqual(
redirects.map((rule) =>
rule.find((line) => line.startsWith("from = "))
),
expectedRules.map(({ from }) => `from = "${from}"`)
);
});

for (const { name, from, to, status } of expectedRules) {
test(name, () => {
const rule = redirects.find((lines) =>
lines.includes(`from = "${from}"`)
);

assert.ok(rule, `Missing routing rule for ${from}`);
// Check each block independently so another rule cannot satisfy it.
// No target query string means Netlify passes query parameters through.
assert.ok(rule.includes(`to = "${to}"`));
assert.ok(rule.includes(`status = ${status}`));
assert.ok(rule.includes("force = true"));
});
}
});
Loading